c++ - 在 GDB 中的捕获点停止后退出

标签 c++ c gdb shared-libraries

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

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

但是,捕获点处的堆栈看起来像这样:

(gdb) bt #0 0x00007ffff7df0632 在 ?? () 来自/lib64/ld-linux-x86-64.so.2 #1 0x00007ffff7dd8c2a 在 ?? () 来自/lib64/ld-linux-x86-64.so.2 #2 0x00007ffff7dd7c38 在 ?? () 来自/lib64/ld-linux-x86-64.so.2 #3 0x000000000000000a 在 ?? () #4 0x00007fffffffde1e 在 ?? () //没有位置信息的几帧

此时,我想从开始加载共享库的地方继续执行我的代码。但是,我在堆栈中看不到我的代码。而且,我不明白frame #3的意思。我无法超出该帧,因为 GDB 无法在堆栈上找到有效的返回地址(这很明显,因为 0xa 绝对不是有效的返回地址)。

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

最佳答案

My understanding of shared libraries tells the following: initially the PLT entry points to some code that loads the lib. When it is called, the library gets loaded and the PLT entry starts pointing to the actual loaded library code so that the next time the lib is called we just jump to its code without reloading.

这种理解是不正确的。

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

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

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

您可以使用 readelf -d a.out | 查看您的二进制文件直接链接到的一组库。需要 grep

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

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

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

您可能对惰性 PLT 解析感到困惑(它与库加载无关)。你可以阅读它here .

关于c++ - 在 GDB 中的捕获点停止后退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46828418/

相关文章:

c++ - RInside 找不到已编译 R 的系统 Renviron

c++ - 为什么在设置 FPS 时在 SDL 中启动计时器?

c++ - 旋转矩阵的方向 vector

c - 读取内核空间中的符号链接(symbolic link)

c++ - 在 gdb 中使用 coredump 时,我如何确切知道哪个线程导致了 SIGSEGV?

c++ - LDAP长消息长度表示

c++ - 使用 "operator T*()"而不是 "T* operator->()"进行成员访问

c - 从 C 中的单词列表中选择一个随机单词的问题

c - 从 ELF 文件生成完整上下文符号表

c - 使用 gdb 进入内核源代码