在GDB中停留在捕获点后退出

时间:2017-10-19 11:01:12

标签: c++ c gdb shared-libraries

为了调试我的程序,我需要在加载共享库之后看到发生了什么。我使用GDB的catch load命令来停止共享库事件。

我对共享库的理解告诉我们:最初PLT条目指向一些加载lib的代码。当它被调用时,库被加载并且PLT条目开始指向实际加载的库代码,以便下次调用lib时我们只需跳转到它的代码而不重新加载。考虑到这一点,我希望catchpoint位于从PLT调用的某个系统函数中,我希望我的代码在堆栈中更高的位置。

但是,catchpoint的堆栈如下所示:

(gdb) bt #0 0x00007ffff7df0632 in ?? () from /lib64/ld-linux-x86-64.so.2 #1 0x00007ffff7dd8c2a in ?? () from /lib64/ld-linux-x86-64.so.2 #2 0x00007ffff7dd7c38 in ?? () from /lib64/ld-linux-x86-64.so.2 #3 0x000000000000000a in ?? () #4 0x00007fffffffde1e in ?? () // several frames without location info

此时,我想继续从开始加载共享库的位置执行我的代码。但是,我无法在堆栈中看到我的代码。而且,我不理解框架#3的含义。我不能超越那个帧,因为GDB无法在堆栈上找到有效的返回地址(这很明显,因为0xa绝对不是有效的返回地址)。

什么是0xa,为什么它在堆栈上? 有没有办法在加载共享库之后完全停止我的代码中的GDB?

1 个答案:

答案 0 :(得分:0)

  

我对共享库的理解告诉我们:最初PLT条目指向一些加载lib的代码。当它被调用时,库被加载并且PLT条目开始指向实际加载的库代码,以便下次调用lib时我们只需跳转到它的代码而不重新加载。

这种理解是不正确的。

有两种情况需要考虑,它们都不涉及在调用函数时加载库。

案例#1:您的二进制文件直接与共享库链接,如下所示:

gcc main.c -lc  # links against libc.so.6

您可以使用readelf -d a.out | grep NEEDED查看二进制文件直接链接的库集。

在这种情况下,在可执行文件开始运行之前,动态加载程序会加载所有库。

案例#2:您通过dlopen动态添加新库。

在这种情况下,库是从dlopen实现中加载的。

您可能感到困惑的是懒惰的PLT解析(其中没有与库加载有关)。你可以阅读它here