为啥gdb找不到源文件

Posted

技术标签:

【中文标题】为啥gdb找不到源文件【英文标题】:why gdb cannot find source file为什么gdb找不到源文件 【发布时间】:2016-08-11 05:47:29 【问题描述】:

我编译了一个名为libsuperdmgr.so 的动态库。 当我使用 gdb 调试这个库时,它无法链接到源文件。 如下:在第3帧和第4帧可以显示源文件的详细行,但是在第2帧和第1帧到我的lib时,却没有显示详细的行号。

#0  std::operator<< <char, std::char_traits<char>, std::allocator<char> > (__os=..., __str=...)
at /root/gcc/gcc-4.5.1/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.h:2605
#1  0x00007fffc9ba67db in DmgrWrapper::AddDataStorage(NIODataStorage*, int) () from /home/shawu/infra/wqsim/arch/x86_64_Linux/wqsim_shawu/infra/libsuperdmgr.so
#2  0x00007fffc9ba6eb0 in NIODataStorageTester::Initialize(int, char const*, WQSim_Config::Element const*) ()
from /home/shawu/infra/wqsim/arch/x86_64_Linux/wqsim_shawu/infra/libsuperdmgr.so
#3  0x00007ffff543f527 in WQSim_DataRegistry::Handle (this=<value optimized out>, handle=<value optimized out>, cfg=<value optimized out>)
at wqsim/framework/WQSim_dataregistry.cc:618
#4  0x00007ffff588eea1 in WQSim_ModuleHandler::LoadModules (this=<value optimized out>) at wqsim/framework/WQSim_modulehandler.cc:125
#5  0x00007ffff7593586 in wqsim_main_init (argc=<value optimized out>, argv=<value optimized out>) at wqsim/modules/WQSim_main.cc:1016

这是为什么???我在编译时会丢失一些东西吗?

【问题讨论】:

【参考方案1】:

最可能的原因是...共享库是否在调试支持的情况下编译/链接?如果没有,您在二进制代码中没有指向库中源点的指针,因此gdb(1) 无法关注它们,也无法显示您在源代码中的位置。此外,库资源是否可用(如果没有,将很难访问源代码 --- 我知道这个断言很荒谬,但谁知道:))o

如果可以,请使用-g 选项重新编译共享对象库并将其与该选项链接,以保存最终共享对象中的调试信息。

Gdb(1) 具有指示在文件系统中何处定位模块信息的命令,但如果二进制文件中没有用于定位源代码点的指针,则无法访问它。

假设您有一个由两个文件组成的程序:a.cb.c

a.c 具有main() 功能,将成为一个普通的应用程序模块。 b.c 将成为共享库。

要编译您的应用程序,您通常编译 a.c(带有调试信息生成):

cc -g -c a.c -o a.o

要将b.c 编译为您使用的共享对象:

cc -fPIC -g -c b.c -o b.so

但这不是我们最终的可加载共享对象。我们只是将它编译成一个目标文件(对不起,后缀冲突)现在构造共享对象:

cc -g -o libb.so.1.1 -shared -Wl,-soname=b.so.1 b.so

看看我是如何在编译b.c 并将b.so 链接到libb.so.1.1 中包含-g 选项的。

现在,用以下命令行链接程序:

cc -o a.out -g a.o libb.so.1.1

a.out 将收到来自a.ob.so.1.1 的调试信息(但如果你想使用它,你需要在b.so.1.1 中拥有它)

注意

目前我不知道b.so.1.1的调试信息是否包含在a.out的链接阶段的a.out中,或者它必须在运行时从libb.so.1.1收集gdb(1)访问共享库。最可能的情况是它必须存在于库中,因为它是属于库的数据(您可以在程序构建后为您的程序提供共享对象的不同实现,并且调试信息会有所不同)

【讨论】:

以上是关于为啥gdb找不到源文件的主要内容,如果未能解决你的问题,请参考以下文章

gdb:在 0x#number# 处添加的符号文件系统提供的 DSO 中找不到可加载的部分

使用 gdb 对指定可执行文件之外的单步汇编代码导致错误“找不到当前函数的边界”

arcgis为啥要连接文件夹

GDB 警告:在 0x7ffff7ffd000 添加的符号文件系统提供的 DSO 中找不到可加载部分

eclipse 调试模式下的 GDB 找不到 stdlib/rand.c

gdb调试技巧关于源文件路径问题