简体   繁体   English

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

[英]Stepping out after stopping on catchpoint in GDB

In order to debug my program, I need to see what is happening exactly after a shared library was loaded. 为了调试程序,我需要查看在加载共享库后到底发生了什么。 I use GDB's catch load command to stop on shared library events. 我使用GDB的catch load命令在共享库事件上停止。

My understanding of shared libraries tells the following: initially the PLT entry points to some code that loads the lib. 我对共享库的了解如下:首先,PLT条目指向一些加载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. 调用该库时,将加载该库,并且PLT条目开始指向实际加载的库代码,因此,下次调用该lib时,我们将跳转至其代码而无需重新加载。 Taking that into account I expect the catchpoint to be inside some system function that was called from PLT, and I expect my code to be somewhere higher on the stack. 考虑到这一点,我希望捕获点位于从PLT调用的某些系统函数中,并且我希望我的代码在堆栈中更高的位置。

However, the stack at the catchpoint looks like this: 但是,捕获点处的堆栈如下所示:

(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

At this point, I want to continue executing my code from the point where it started loading shared libs. 在这一点上,我想从代码开始加载共享库的地方继续执行我的代码。 However, I cannot see my code in the stack. 但是,我在堆栈中看不到我的代码。 Moreover, I don't understand the meaning of frame #3 . 而且,我不理解#3帧的含义。 I cannot step out further than that frame because GDB is unable to find a valid return address on the stack (which is obvious because 0xa is definitely not a valid return address). 因为GDB无法在堆栈上找到有效的返回地址,所以我无法进一步扩展(这很明显,因为0xa绝对不是有效的返回地址)。

What is 0xa and why is it on the stack? 什么是0xa ,为什么在堆栈上? Is there a way to stop GDB in my code exactly after the shared library was loaded? 共享库加载后,有没有一种方法可以在我的代码中立即停止GDB?

My understanding of shared libraries tells the following: initially the PLT entry points to some code that loads the lib. 我对共享库的了解如下:首先,PLT条目指向一些加载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. 调用该库时,将加载该库,并且PLT条目开始指向实际加载的库代码,因此,下次调用该lib时,我们将跳转至其代码而无需重新加载。

This understanding is incorrect. 这种理解是不正确的。

There are two cases to consider, and neither of them involves loading the library when a function from it is called. 有两种情况需要考虑,两种都不涉及在调用库中的函数时加载库。

Case #1: your binary is linked against shared library directly, like so: 案例1:您的二进制文件直接链接到共享库,如下所示:

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

You can see the set of libraries that your binary is directly linked against with readelf -d a.out | grep NEEDED 您可以看到二进制文件与readelf -d a.out | grep NEEDED直接链接的一组库readelf -d a.out | grep NEEDED readelf -d a.out | grep NEEDED . readelf -d a.out | grep NEEDED

In this case, all the libraries are loaded by the dynamic loader before the executable starts running. 在这种情况下,在可执行程序开始运行之前,所有库都由动态加载程序加载。

Case #2: you dynamically add a new library via dlopen . 情况2:您通过dlopen动态添加新库。

In that case, the library is loaded from within dlopen implementation. 在这种情况下,该库是从dlopen实现中加载的。

What you are likely confused about is lazy PLT resolution (which has nothing to do with library loading). 您可能会感到困惑的是延迟PLT解析(与库加载无关 )。 You can read about it here . 你可以在这里阅读。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM