如何用GDB调试通过LD_LIBRARY_PATH/LD_PRELOAD启动的带补丁libc的程序?
解决GDB与被调试程序libc分离调试的问题
我来帮你搞定这个棘手的调试场景——核心就是把GDB自身的libc依赖和被调试程序的完全隔离开,同时让ASAN的错误能被GDB精准捕获。下面是一步步的实操方案:
1. 用系统原生libc启动GDB
你的补丁libc有问题,绝对不能让GDB加载它。我们直接清空环境变量,手动指定GDB只使用系统默认的库路径:
env -i LD_LIBRARY_PATH=/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu PATH="$PATH" TERM="$TERM" gdb
小贴士:你可以用
gcc --print-file-name=libc.so命令确认Debian10系统libc的准确路径,替换上面的路径即可。env -i会清空所有现有环境变量,我们只保留必要的PATH(让GDB能找到命令)和TERM(保证终端显示正常)。
2. 在GDB内部为被调试程序设置专属环境
进入GDB后,先给要调试的./binary设置它需要的环境变量,让它加载你的补丁libc、共享库和ASAN:
set environment LD_LIBRARY_PATH="./path/to/libc_patched:/path/to/shared" set environment LD_PRELOAD="/path/to/libasan.so /path/to/libc_patched"
注意路径最好用绝对路径,或者相对于GDB当前工作目录的相对路径,避免因路径解析出错导致加载失败。
3. 配置ASAN与GDB的联动
ASAN默认检测到错误会直接终止程序,我们可以设置环境变量让它在出错时暂停,方便GDB捕获现场:
set environment ASAN_OPTIONS="abort_on_error=1:halt_on_error=1"
然后加载你的程序,并开启断点支持:
file ./binary set confirm off set breakpoint pending on
4. 启动调试定位错误
现在可以启动程序了:
run
当ASAN检测到malloc/free不匹配这类错误时,程序会触发SIGABRT,GDB会自动停在错误发生的位置。此时你可以用这些命令排查:
bt:查看完整调用栈,找到错误的源头frame <栈帧编号>:切换到对应的栈帧,查看具体代码info locals:查看当前栈帧的局部变量,辅助分析问题
额外注意事项
- 确保
libasan.so的版本和你编译程序时用的GCC版本匹配:Debian10默认是GCC8,对应的ASAN库是libasan5.so,通常在/usr/lib/x86_64-linux-gnu/目录下。 - 如果你的补丁libc是自行编译的,记得编译时加上
-g参数,这样GDB能显示补丁libc内部的源码/汇编位置,更方便排查补丁引入的问题。 - 要是发现GDB还是加载了补丁libc,你可以用
show environment LD_LIBRARY_PATH在GDB里检查环境变量,或者用ldd $(which gdb)确认GDB自身的依赖库是否正确指向系统libc。
内容的提问来源于stack exchange,提问作者MajorasKid
相关产品推荐
相关产品推荐

