I'm seeing an odd issue when trying to use gdb to debug a test program for a package built with libtool. If I run libtool --mode=execute gdb .libs/libfoo.so
and ask it to list the source of some function list Bar::Baz
, I get the source code as expected. If I run libtool --mode=execute gdb binary
, I can break in Bar::Baz()
, and see its arguments in a stack trace, but I get no source file or line numbers, like so:
#7 0x018348e5 in Bar::Baz(Qux*, Quux*) () from /path/to/libfoo.so
^^^^^^^^^^^ <--- debug symbols are present!
Similarly, if I try to list Bar::Baz
when debugging the executable, I get
No line number known for 'Bar::Baz'.
I have confirmed that the binary is linked with -g
, and I can list its main
function, so I know some of the debug information is present are present.
When I say info sources
, I get a full listing of the files from which the library is built, with correct absolute paths. When I say info shared
, I get the correct path listed to the object file, with a Yes
in the Syms
column.
Any further ideas what could be going wrong, and how to fix it?
Edit 1: By accident, I ran objdump -g
on the offending library, and got the following output:
/path/to/foo.so.0.0.0: file format elf32-i386
objdump: /path/to/foo.so.0.0.0: no recognized debugging information
This is surprising, since objdump -h
(what I had tried to run) lists a bunch of .debug_*
sections. The objdump
manual suggests readelf -w
as well, and that seems to print a huge pile of information. I need to go look through at what it actually provides, though.
Edit 2: So, readelf -w
has produced some enlightenment. For whatever reason, the shared object file doesn't seem to contain the debugging information from the vast majority any of the objects linked into it. Based on the Makefiles, it's possible that the command that actually gathers up the objects into the shared library isn't passed -g
, and so that information isn't properly propagated. The funny thing is that this works (has full debug information) on all our other configurations, including the same compiler version on x86_64 (versus the present x86).
Edit 3: Actually went through a full rebuild with the modified Makefile with -g added on the LDFLAGS, and it made no difference. Now I'm well and truly baffled.
This is an answer to an old question, but your problem matched mine, but none of the solutions worked. Here is what worked for me.
Change CFLAGS -g to "-g -gstabs".
objdump was not recognizing the dwarf style debug information. -gstabs changes this format to one that works with objdump -g and objdump -S and my debugger.
Hope it helps.
NOTE: For me, I was building a linux kernel. This change was make in the linux kernel's Makefile.
Your first point of confusion: Bar::Baz(Qux*, Quux*)
does not imply that debug symbols are present (and in fact implies that they are not present).
The debugger merely demangles the function name. If the debug symbols were in fact present, you'd see Bar::Baz(Qux* qux = 0x12..., Quux* quux = 0x234...)
As for the real problem, I suspect that the symbol is defined in some other library, which
libfoo.so
does, and(The runtime loader will bind the reference to Bar::Baz()
to the first definition it sees.)
If you print ip
in frame #7, then do info symbol <value-just-printed>
, I suspect you'll have an "Aha!" moment.
EDIT: Your update made your question self-inconsistent. AFAICT,
gdb
can see debug symbols when you executelibtool --mode=execute gdb .libs/libfoo.so
libtool --mode=execute gdb binary
.libs/libfoo.o
readelf -w
doesn't see debug symbols in .libs/libfoo.o
At least one of the above statements is likely false.
If they are all really true, you probably have a weird GDB
and readelf
bug (a bug in one is possible, a simultaneous bug in both is somewhat unlikely).
Also note that adding -g
to LDFLAGS
is generally the wrong thing to do. Did you mean to add it to CXXFLAGS
instead?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With