Phi*_*ler 4 gdb debug-symbols libtool dwarf
当我尝试使用gdb来调试使用libtool构建的包的测试程序时,我发现了一个奇怪的问题.如果我运行libtool --mode=execute gdb .libs/libfoo.so并要求它列出某些函数list Bar::Baz的源代码,我会按预期获得源代码.如果我运行libtool --mode=execute gdb binary,我可以闯入Bar::Baz(),并在堆栈跟踪中查看其参数,但我没有得到源文件或行号,如下所示:
#7 0x018348e5 in Bar::Baz(Qux*, Quux*) () from /path/to/libfoo.so
^^^^^^^^^^^ <--- debug symbols are present!
Run Code Online (Sandbox Code Playgroud)
同样,如果我list Bar::Baz在调试可执行文件时尝试,我会得到
No line number known for 'Bar::Baz'.
Run Code Online (Sandbox Code Playgroud)
我已经确认二进制文件是链接的-g,我可以列出它的main功能,所以我知道存在一些调试信息.
当我说info sources,我得到了构建库的文件的完整列表,具有正确的绝对路径.当我说info shared,我得到正确的路径列出到目标文件,Yes在Syms列中有一个.
什么可能出错的其他想法,以及如何解决它?
编辑1:偶然地,我objdump -g在违规库上运行,并得到以下输出:
/path/to/foo.so.0.0.0: file format elf32-i386
objdump: /path/to/foo.so.0.0.0: no recognized debugging information
Run Code Online (Sandbox Code Playgroud)
这是令人惊讶的,因为objdump -h(我试图运行)列出了一堆.debug_*部分.该objdump手册也表明readelf -w,这似乎打印了大量的信息.不过,我需要仔细研究它实际提供的内容.
编辑2:所以,readelf -w产生了一些启示.无论出于何种原因,共享对象文件似乎不包含从调试信息绝大多数 的任何链接到它的对象.基于Makefile,实际上将对象收集到共享库中的命令可能不会被传递-g,因此信息没有被正确传播.有趣的是,这在我们所有其他配置上都有效(包含完整的调试信息),包括x86_64上的相同编译器版本(与现在的x86相比).
编辑3:实际上在LDFLAGS上使用-g添加了修改后的Makefile进行完全重建,并没有任何区别.现在我很好,真的很困惑.
这是一个老问题的答案,但你的问题与我的问题相符,但没有一个解决方案有效.这对我有用.
将CFLAGS -g更改为"-g -gstabs".
objdump没有认识到矮人风格的调试信息.-gstabs将此格式更改为与objdump -g和objdump -S以及我的调试器一起使用的格式.
希望能帮助到你.
注意:对我来说,我正在构建一个Linux内核.这个改变是在linux内核的Makefile中进行的.
您的第一点困惑:Bar::Baz(Qux*, Quux*)并不意味着存在调试符号(实际上意味着它们不存在)。
调试器仅对函数名称进行解析。如果调试符号确实存在,您会看到Bar::Baz(Qux* qux = 0x12..., Quux* quux = 0x234...)
至于真正的问题,我怀疑该符号是在其他库中定义的,其中
libfoo.so,并且(运行时加载程序会将引用绑定到Bar::Baz()它看到的第一个定义。)
如果您ip在第 7 帧中打印,然后执行info symbol <value-just-printed>,我怀疑您会“啊哈!” 片刻。
编辑:您的更新使您的问题自相矛盾。亚洲信息通信技术协会,
gdb执行时可以看到调试符号libtool --mode=execute gdb .libs/libfoo.solibtool --mode=execute gdb binary.libs/libfoo.oreadelf -w没有看到调试符号.libs/libfoo.o上述陈述至少有一项可能是错误的。
如果它们都是真的,那么您可能会遇到一个奇怪GDB 的 readelf错误(其中一个错误是可能的,两个同时出现错误的可能性不太可能)。
另请注意,添加-g到LDFLAGS通常是错误的做法。您的意思是添加它CXXFLAGS吗?