能调试动态库需满足三前提:编译带-g、运行时已加载、GDB能定位符号;缺一则出现函数找不到或断点pending,如break后提示“Make breakpoint pending on future shared library load?”。

能调试,但得满足三个前提:动态库编译时带 -g、运行时已加载、GDB 能定位到它的符号。缺一不可,否则会卡在“函数找不到”或“断点 pending”。
动态库没加载就下断点,GDB 只能挂起等待
常见现象是输入 break lib_function 后,GDB 提示:
Function "lib_function" not defined.<br>Make breakpoint pending on future shared library load? (y or n)
这不是错误,而是 GDB 在说:“这函数现在不在内存里,等它被 dlopen 或启动时自动加载了,我再帮你打。”
- 如果程序用
main启动且动态库在链接时声明(如-lsimple),运行run后库通常立即加载,pending 断点会自动激活 - 如果用
dlopen延迟加载,必须先执行到dlopen调用之后,再手动触发sharedlibrary或等 GDB 自动检测 - 别在
start后立刻下断点——此时_dl_open还没跑,库根本没进地址空间
info sharedlibrary 显示 No shared libraries loaded
说明 GDB 当前看不到任何已加载的 .so,原因很实际:
- 程序还没
run,停留在入口点(_start),动态链接器尚未介入 - 动态库路径不在
LD_LIBRARY_PATH里,导致加载失败静默退出(可用ldd ./executable验证) - 用了
set follow-fork-mode child但子进程才加载库,而你停在父进程里
解决方法直白:先 run,等报错或停在 main 再查;或者用 catch load 捕获库加载事件,比盲等更可靠。
符号加载对了,但断点不命中源码行
典型表现是 break lib_function 成功,但 step 进不去,或 list 显示“No symbol table is loaded”。
- 确认动态库编译用了
-fPIC -g,缺-fPIC可能链接失败,缺-g则无调试信息 - 检查
objdump -t libexample.so | grep debug,有输出才说明调试段存在 - 若库在非标准路径(比如
./libs/libexample.so),必须提前设set solib-search-path ./libs,否则 GDB 找不到符号文件 - 用
info sources看 GDB 是否列出了你的 .c 文件路径;没有?说明源码路径和编译时不符,需用directory /path/to/src补充
崩溃发生在动态库中,但 backtrace 显示 ??
核心转储(core dump)里看到类似:
#5 0x00007f8b2a1c3476 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
这意味着该帧的符号没加载或被 strip 过。
- 优先检查崩溃时的动态库是否和编译调试版一致(
readelf -n core | grep BuildID对比readelf -n libexample.so) - 如果用了分离调试符号(
objcopy --only-keep-debug),必须在 GDB 中显式symbol-file libexample.debug -
bt full比bt更可能暴露寄存器值和局部变量,有时能绕过符号缺失看到关键线索
最易被忽略的一点:GDB 不会自动 reload 动态库符号,哪怕你改了代码重新编译了 .so。每次换库,都得 sharedlibrary libexample.so 或重启 GDB,否则它还在用旧符号表。


















