Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Gdb 在整个程序中,库的调试符号中缺少行号,但本身没有_Gdb_Debug Symbols_Libtool_Dwarf - Fatal编程技术网

Gdb 在整个程序中,库的调试符号中缺少行号,但本身没有

Gdb 在整个程序中,库的调试符号中缺少行号,但本身没有,gdb,debug-symbols,libtool,dwarf,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

在尝试使用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!
我已经确认二进制文件与
-g
链接,并且我可以列出它的
主功能
,因此我知道存在一些调试信息

当我说
infosources
时,我得到了构建库的文件的完整列表,以及正确的绝对路径。当我说
info shared
时,我得到了目标文件的正确路径,在
Syms
列中有一个
Yes

有没有进一步的想法,可能出现什么问题,以及如何解决


编辑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
这是令人惊讶的,因为
objdump-h
(我尝试运行的)列出了一堆
.debug.*
部分。
objdump
手册也建议使用
readelf-w
,这似乎打印了大量信息。不过,我需要仔细看看它到底提供了什么


编辑2:因此,
readelf-w
产生了一些启示。无论出于何种原因,共享对象文件似乎不包含绝大多数链接到其中的对象的调试信息。基于Makefiles,可能没有传递将对象实际收集到共享库中的命令
-g
,因此信息没有正确传播。有趣的是,它在所有其他配置上都有效(包含完整的调试信息),包括x86_64上的相同编译器版本(与当前的x86相比)



编辑3:实际上,通过在LDFLAGS上添加-g的修改过的Makefile进行了完整的重建,没有任何区别。现在我真的很困惑。

您的第一个困惑点:
Bar::Baz(Qux*,Qux*)
并不意味着调试符号存在(实际上意味着它们不存在)

调试器仅要求函数名。如果调试符号确实存在,您将看到
Bar::Baz(Qux*Qux=0x12…,Qux*Qux=0x234…

至于真正的问题,我怀疑符号是在其他库中定义的,而

  • 出现在
    libfoo之前的二进制文件的链接行上。因此
    会出现,并且
  • 是在没有调试符号的情况下生成的
(运行时加载程序将对
Bar::Baz()
的引用绑定到它看到的第一个定义。)

如果您在第7帧中打印
ip
,然后执行
info symbol
,我怀疑您会有一个“啊哈!”的时刻

编辑:您的更新使您的问题自相矛盾。AFAICT

  • gdb
    在执行时可以看到调试符号
    libtool--mode=executegdb.libs/libfoo.so
  • 但当您执行
    libtool--mode=executegdbinary
  • 您已验证符号定义是否来自 完全相同的
    .libs/libfoo.o
  • 并且
    readelf-w
    .libs/libfoo.o
  • 上述陈述中至少有一项可能是错误的

    如果它们都是真的,那么您可能有一个奇怪的
    GDB
    readelf
    错误(一个错误中可能有一个,两个错误中同时出现的可能性不大)


    还要注意,将
    -g
    添加到
    LDFLAGS
    通常是错误的。您是想将其添加到
    cxflags
    中吗?

    有件事让我想知道当您体验到
    show language
    时,它的输出是什么
    问题。如果不是
    c++
    ,那么可能需要
    set语言c++

    这是一个老问题的答案,但你的问题与我的问题相匹配,但没有一个解决方案有效。这是对我有用的东西

    将CFLAGS-g更改为“-g-gstabs”

    objdump无法识别dwarf样式的调试信息-gstabs将此格式更改为与objdump-g和objdump-S以及我的调试器一起使用的格式

    希望能有帮助


    注意:对我来说,我正在构建一个linux内核。这个更改是在linux内核的Makefile中进行的。

    关于名称mangling,这是一个很好的观点。明天早上我会仔细看看到底是什么联系在一起的。我怀疑是否涉及到错误的库,因为二进制文件是一个测试程序,与它应该测试的库的唯一可见实例构建在同一棵树中-没有系统安装或类似的东西需要处理。我刚刚检查了这个,链接的库就是我期望的库。我的一个拼写错误导致了一个有趣的发现,我将用它来修正原来的问题。如果你(或其他阅读本文的人)有其他想法,我会全神贯注地听(真的是眼睛)。我最近又遇到了一次关于这个问题的重演。这次是GCC4.9对GDB7.2。编译器正在生成DWARF v4,而调试器最多只能理解DWARF v3。升级调试器解决了这个问题。作为一种解决方法,传递
    -gdwarf-3
    告诉它吐出旧的格式符号。
    /path/to/foo.so.0.0.0: file format elf32-i386
    objdump: /path/to/foo.so.0.0.0: no recognized debugging information