如何使用 GDB 调试共享对象库中的函数?

Posted

技术标签:

【中文标题】如何使用 GDB 调试共享对象库中的函数?【英文标题】:How can I debug functions in shared object libraries with GDB? 【发布时间】:2020-04-28 15:37:43 【问题描述】:

我正在尝试验证共享对象库中函数的功能。在带有 main 函数的程序中,我会简单地 start 程序和 gdb 会自动在 main 上断点,但这显然在这里不可用。

假设我有一些add.c

long add(long x, long y) 
    return x + y;

我用 gcc -shared -o libadd.so -fPIC add.c 编译它并将它加载到 GDB 中:

(gdb) file libadd.so
Reading symbols from libadd.so...(no debugging symbols found)...done.
(gdb) start
Function "main" not defined.
Make breakpoint pending on future shared library load? (y or [n])
Starting program: /tmp/minimal/libadd.so

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000001 in ?? ()

我希望能够使用类似于以下的 gdb:

(gdb) file libadd.so
Reading symbols from libadd.so...(no debugging symbols found)...done.
(gdb) call (long)add(5,6)
$1 = 11

但是这个调用的结果是You can't do that without a process to debug

我可以在 GDB 中调试这样的库吗?

【问题讨论】:

很好的规范问题。两者都 +1。 @JL2210 昨天我花了 3 到 4 个小时才弄清楚这一点。认为它可能在未来对其他人有用,因为这让我觉得这是一个相当普遍的问题。 您现在应该接受自己的答案,以使该问题看起来与问题列表中的答案相同。 【参考方案1】:

您可以使用starti 进行操作,如下所示:

(gdb) file libadd.so
Reading symbols from libadd.so...(no debugging symbols found)...done.
(gdb) starti
Starting program /tmp/minimal/libadd.so

Program stopped.
0x00007ffff7dfd4a0 in deregister_tm_clones ()
(gdb) call (long)add(5,6)
$1 = 11

您也可以使用包含 main 函数的二进制文件来执行此操作,如 this similar question 中所示。

【讨论】:

未定义命令:“starti”。试试“帮助”。 从 GDB 8.1 开始 由于某种原因,我在调用函数时发现此段错误....【参考方案2】:

一种方法是创建一个链接共享库的虚拟可执行文件:

#include "thelib.h"

int main(int argc, char** argv) 
    if (argc == 100000) 
        // Call any function from the library, so that the shared library will be used
        sub(0, 0);
    

然后,编译和调试这个可执行文件,链接到共享库:

$ gdb dummy
(gdb) start
(gdb) call (long)add(5, 6)

【讨论】:

以上是关于如何使用 GDB 调试共享对象库中的函数?的主要内容,如果未能解决你的问题,请参考以下文章

iOS 5.1 - GDB 命令或实用程序列出特定共享库中的函数

如何使用GDB调试多线程

如何在 Linux 的 QTCreator 中使用 dlopen 打开的共享库中设置断点

如何使用 gdb 制作一个可以漂亮地打印每个对象的 C++ 函数?

当另一个库具有相同的符号时,gdb 不显示来自共享库的符号

如何停止在共享库中实现的阻塞 pthread_join()