[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Building -dbg libraries



[REPOST: I've already posted this three days ago, but I haven't seen it
on the list, nor I've seen any reply, so I suppose it's vanished
somewhere. I apologize to those who get it twice]


On  8 Jan, Guy Maor wrote:
> Fabrizio Polacco <fpolacco@icenet.fi> writes:
> 
>> I recently managed to add some sources in my -dbg shared lib packages,
>> to make them easily debuggable. (See bug#16038 on 30 Dec)
> 
> I rather liked your solution to the problem of debuggable shared libs,
> but you need to figure out a way to not need to be root to build
> it. (maybe you already did?)

I did.

You don't need any more to be in group "src" or to change mode to
/usr/src (being root wasn't required to build, although obviously 
worked :-)

You should read my last post to bug#16038 (what's the url?) for a long
explanation of what I've done.

Anyway I applied my ideas both to libdb2 and liblockdev0g; the latter
is a pristine debian source of only 20k, so I think it is simpler to
examine.

The idea behind all this is to have a -dbg package that permits
debugging (of the library, not of your program) just out of the box,
without any need for unpacking, patching sources, etc.
It is quite annoying, when debugging a program, to have to skip
library's routines without having the possibility to inspect the code
and the data. This method permits to add one or more libraries to your
debug simply installing the relative -dbg packages, which I suggest to
keep on your machine in .deb format, as those libs are usually highly
compressable.

To debug:
	1) install the -dbg package.
	2) become the owner of the executable on which you want 
	   to run gdb,
	3) preload the debug location with
	   LD_LIBRARY_PATH=/usr/lib/debug gdb <executable>

Note that only step one must be repeated for each of the libraries you
want to debug, while the other two are relative to the debug session.

Step 2 can be a problem when debugging setuid programs; in case the
program is owned by a non-login user, become root and issue
	su user -c "LD_LIBRARY_PATH=/usr/lib/debug gdb <executable>"
Anyway, with this method you can run gdb also on "preinstalled"
executables, when you want to debug the library itself (no need to
compile an ad-hoc program just to have the relative objects loaded).


To build the -dbg lib:
	1) provide the needed sources for listing in gdb.
	2) put in the symbol table of the lib the exact location 
	   of the sources.
	3) build unstripped shared libs compiled with -DDEBUG.
	4) name the lib with the "soname" used in the runtime lib.
	5) install the lib in a location NOT known by ld.so
	6) DON'T run ldconfig with that location

The following description seems to be more appropriate for
debian-mentors that debian-policy. I put it here just to avoid future
endless discussion on "how this could be ever done?" :-)


1) provide the needed sources for listing in gdb.

the correct place is IMHO /usr/src/<package><version> (whatever else?)
I do this in the debian/rules makefile with the following command:

	# ==== sources ====
	${install_sources}

   <NOTE> to avoid involution of code in the debian/rules file, I use
   the "define" ability of make; I also put all these defines in a
   separated file (that I copy in all my packages) that goes included
   in the debian/rules file. </NOTE>

define install_sources
for src in `strings -a ${d_ulib}/debug/* | grep '$(abs_src)' | sort -u` ; \
do      for fullname in $${src} ; \
        do      fulldir=`dirname $${fullname}` ; \
                ${install_dir}  ${d_build}$${fulldir} ; \
                localname=`echo $${fullname} | sed 's,^${abs_src}/,,'` ; \
                ls $${localname} 2>/dev/null \
                && ${install_data} $${localname} ${d_build}$${fullname}  ; \
done; done;
endef
this_dir=${shell pwd}
abs_src = /usr/src/$(shell basename ${this_dir})
d_build = ${absolute_d_build}
d_ulib  = ${d_build}/usr/lib
install_dir  = install -p -o root -g root -m 755 -d
install_data = install -p -o root -g root -m 644



2) put in the symbol table of the lib the exact location of the sources.

This step is the most difficult to accomplish, as the debianized source
can be located everywhere (by policy). 
The first solution was to provide a symlink to the absolute location
where the sources _will_ be installed, and compile adding that path to
the sources names. See bug#16038 to see why this wasn't a good idea :-)

Now I used a different solution, which may have different problems on
different packages (and different makefiles). The makefiles I built for
those two libs use implicit rules (I like simplicity :-), so I used
the overwriting method to do something different when compiling for the
-dbg package (sources should be recompiled ad-hoc for -dbg using
-DDEBUG, which should be not set when compiling for runtime lib) 

ifdef create_debug_lib

_SRCDIR_:
        ln -sf . $@

# overwriting implicit rule
%.o: %.c _SRCDIR_
        @echo "=== overwritten rule .o:.c ($@: $^) ==="
        ${COMPILE.c} -S _SRCDIR_/$< -o $*.ss
        sed 's,^.stabs \"_SRCDIR_\/,.stabs \"${abs_src}/,' $*.ss > $*.s
        ${COMPILE.s} -o $@ $*.s
        ${RM} $*.ss $*.s

endif # create_debug_lib


This fragment have to be included in the makefile.
In the rules file, when compiling the -dbg package, issue

        ${MAKE} shared CFLAGS="-g3 -O2 -fPIC -DDEBUG" create_debug_lib=1

where the setting of the var "create_debug_lib" has the effect to
overwrite the implicit rule, getting the change of the pathname in the
symbol table.

This provides step two. The problem is that most of the upstream author
have "strange" ideas on how a makefile should be done, and probably you
have to change it to get what you want. In that cases I find more
simple for me (and for a reader also) to create a new makefile from
scratch. I did so for libdb2, after having wasted hours to modify the
upstream one :-)
The new makefile uses the old one to build a list of objects, and let
the implicit rules do all the rest; it fills only one screen.

        It's my opinion that the _only_ skill that we should require
        in a Debian Developer is GNU Make knowledge.



That's all.

comments wellcome.

Fabrizio
-- 
| fpolacco@icenet.fi    fpolacco@debian.org    fpolacco@pluto.linux.it
| Pluto Leader - Debian Developer & Happy Debian 1.3.1 User - vi-holic
| 6F7267F5 fingerprint 57 16 C4 ED C9 86 40 7B 1A 69 A1 66 EC FB D2 5E
> more than 35 months are needed to get rid of the millennium. [me]



Reply to: