gdb:如何了解哪个共享库加载了有问题的共享库

gdb: how to learn which shared library loaded a shared library in question

我需要获取应用程序在运行时使用的共享库列表。其中大部分可以通过 ldd 列出,但有些只能通过 gdb -p <pid> 和 运行 gdb 命令 info sharedlib.

才能看到

如果我能以某种方式学习,那真的很有帮助:对于一个选定的库(在列表中,由 info sharedlib 输出),哪个库(在同一个列表中)导致加载它。有什么方法可以在 gdb 或其他方式中学习它吗?因为有时,我在列表中看到一个已加载的库,但无法理解为什么它在那里以及哪个(可能之前已加载到内存中)库加载了它。

更新:

我附上了显示我需要的信息的 gdb 屏幕截图。我在 dlopen 上使用了断点,正如评论和答案中所建议的那样。命令 x/s $rdi 打印出 dlopen 的第一个参数,如 Linux System V ABI,即它打印库的名称,我想知道是谁加载了它(libdebuginfod.so.1).我把它放在这里只是为了那些好奇的人。在我的例子中,可以看出 libdebuginfod.so.1 是由 libdw.so.1 加载的(如 bt 命令所示)。

Is there any way to learn it in gdb or in some other way?

有几种方法。

您可以 运行 使用 env LD_DEBUG=files /path/to/exe 的程序。

这将产生类似于以下内容的输出:

 LD_DEBUG=files /bin/date
     76042:
     76042:     file=libc.so.6 [0];  needed by /bin/date [0]

这是您最关心的 所需的部分。

您也可以使用 GDB 并使用 set set stop-on-solib-events 1。这将产生类似于:

的输出
Stopped due to shared library event:
  Inferior loaded /lib/x86_64-linux-gnu/libc.so.6

此时,您可以执行 where 命令并观察哪个 dlopen() 调用导致加载新库。

您也可以在 dlopen() 上设置断点并执行相同的操作。

如果您的可执行文件重复 dlopen() 同一个库,stop-on-solib-events 可能会更好——当您再次 dlopen() 同一个库时,库集不会改变,并且您当你不想停下来的时候就会停下来。设置 stop-on-solib-events 可以避免这种不必要的停止。