如何将 gdb 与 LD_PRELOAD 一起使用

Posted

技术标签:

【中文标题】如何将 gdb 与 LD_PRELOAD 一起使用【英文标题】:How to use gdb with LD_PRELOAD 【发布时间】:2012-05-13 23:08:23 【问题描述】:

我运行一个带有 LD_PRELOADing 特定库的程序。像这样。

LD_PRELOAD=./my.so ./my_program

如何使用gdb 运行这个程序?

【问题讨论】:

【参考方案1】:

我在 VS Code 中使用 gdbserver,最简单的方法是启动你的程序,包裹在 shell 中:

gdbserver :8888 sh -c 'LD_PRELOAD=/libtest.so your_prog'

【讨论】:

【参考方案2】:

执行以下操作。

gdb your_program

(gdb) set environment LD_PRELOAD ./yourso.so
(gdb) start

【讨论】:

【参考方案3】:

这是一种将所有内容(带有参数和环境)作为一个命令运行的方法:

例子:

gdb --args env LD_PRELOAD=/usr/local/lib/libstderred.so ls -l

敏锐的观察者会注意到 env 在这里充当 exec 包装器(就像 Alexey Romanov 的回答一样)。

【讨论】:

【参考方案4】:

您可以使用 -iex 标志在命令行上将 env 作为 exec-wrapper 提供:

gdb -iex "set exec-wrapper env LD_PRELOAD=./my.so" ./my_program

【讨论】:

【参考方案5】:

发布是因为我们遇到了set environment 不起作用的情况:

来自GDB documentation:

set exec-wrapper wrapper
show exec-wrapper
unset exec-wrapper

当设置了'exec-wrapper'时,指定的包装器用于启动程序进行调试。 gdb 使用 exec wrapper program 形式的 shell 命令启动您的程序。引号会添加到程序及其参数中,但不会添加到包装器中,因此您应该在适合您的 shell 时添加引号。包装器一直运行,直到它执行您的程序,然后 gdb 获得控制权。

您可以使用任何最终调用 execve 及其参数的程序作为包装器。几个标准的 Unix 实用程序可以做到这一点,例如环境和nohup。任何以 exec "$@" 结尾的 Unix shell 脚本也可以工作。

例如,您可以使用 env 将环境变量传递给被调试程序,而无需在 shell 的环境中设置该变量

         (gdb) set exec-wrapper env 'LD_PRELOAD=libtest.so'
         (gdb) run

【讨论】:

【参考方案6】:

你基本上可以这样做,只需在程序名称前添加gdb即可:

LD_PRELOAD=./my.so gdb ./my.program

您可以使用以下方法检查环境变量:

(gdb) show environment LD_PRELOAD

在极少数情况下,您实际上需要在 gdb 中更改它,例如在调试dlopen() 时,您可以这样做:

(gdb) set environment LD_PRELOAD ./my.so

哦,等等,gdb 7.6.2 不适用于我!库没有被加载,这意味着这里没有一个答案是完全正确的,至少在当前的工具中是这样。

【讨论】:

我猜预加载的效果对于 GDB 本身来说是不需要的(也许它是一个修改 open() 等的模拟库 - 例如 fakeroot 等)。

以上是关于如何将 gdb 与 LD_PRELOAD 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何使 GDB 与外部程序一起工作

将 CUDA-gdb 与 NVRTC 一起使用

在运行时将函数与 LD_PRELOAD 链接

自行卸载的 Linux 共享库

使用LD_PRELOAD指定多个文件

如何包含 GDB 调试符号“破坏包”?