gdb 是否支持选择性的 `auto-solib-add`?

Does gdb support selective `auto-solib-add`?

我正在调试一个大型命令行程序,它会在启动时加载许多 *.so 库。

如果 auto-solib-addon,加载的符号太多,gdb 就会挂起。因此,我们的最佳做法是在 .gdbinit 中关闭 auto-solib-add 并通过 sharedlibrary.

手动加载所选库的符号

有些*.so库我们不能在程序启动后运行 sharedlibrary,因为这些库还没有加载。我们需要在程序中执行一个命令,比如 dosomething 来触发这些库的加载。之后,这些库将在 gdb 中可见 sharedlibrary

这适用于大多数调试场景,但有一种情况我遇到了麻烦。通过 dosomething 加载的库之一称为 libfoo.so,其 API foo()dosomething 期间执行。如何在 dosomething 期间进入 foo()?换句话说,根据程序阶段的以下心理图像,我如何在 stage j 之后和 stage k 之前暂停 gdb 以便我可以在执行 foo() 之前加载符号?

* ...
* Stage i: In the main program interface, the command `dosomething` is issued. This will trigger the loading of some dynamic linked libraries, including `libfoo.so`.
* ...
* Stage j: `libfoo.so` is loaded.
* ...
* Stage k: `foo()` is executed.
* ...
* Stage l: The command `dosomething` finishes and returns the control to the user in the main program.
* ...

注意:由于某些技术原因,我也无法在主程序启动后和运行 dosomething 触发加载那些库之前打开auto-solib-add。否则,我知道这可能是一种解决方法,而不是尝试在 stage jstage k 之间的最佳位置手动暂停。

My mental image is that the following happens in order:

您的心智模型不正确:如果您可以调用 foo(),那么 定义 foo() 的库一定已经加载。没有 .so 文件的“按需”加载——它们 加载,因为可执行文件直接链接到 .so(在这种情况下 .so 在可执行文件的单个指令运行之前加载), 作为 dlopen() 调用的结果。

您可以通过在 foo()caller 上设置断点并使用 GDB info shared 命令检查所有加载的 .so 来验证这一点]s.

假设 libfoo.so 实际上已经加载,你可以要求 GDB 使用 shared libfoo.so 命令为这个库添加符号。之后,您将能够在 foo() .

上设置断点

如果libfoo.soinfo shared输出中不是,那么你没有准确描述你的程序,你的问题无法回答。

我通过阅读这篇文章开始思考:https://developer.ibm.com/technologies/linux/tutorials/l-dynamic-libraries/

如果我们将三个库的使用场景编号为:

  1. 静态库。
  2. 共享库动态链接。
  3. 共享库动态加载。

libfoo.so 的加载属于 3),其中 dlopen 库用于触发从应用程序加载(但仍然通过处理 2 的系统动态链接器)。

运行 程序启动后 gdb 中的以下内容将允许我们停止每次动态加载。

sharedlibrary libdl.so
b dlopen

我在 stage jstage k 之间寻找的点可能就在 dlopen returns 之后到它的调用者 libfoo.so.