因为动态库符号在程序运行前未加载,gdb无法识别函数名;需先执行run触发动态库加载,再用info sharedlibrary确认符号已读入,或手动加载符号表。

为什么break func_name直接报“Function not defined”
因为动态库的符号在程序启动时还没加载进内存,GDB 在 run 之前根本看不到它的函数名。这不是你写错了,而是加载时机问题——GDB 此时连 libmylib.so 在哪、有没有被用都不知道。常见现象是:(gdb) info sharedlibrary 返回 No shared libraries loaded at this time,或者虽有库但 info functions my_func 查不到。
必须先让动态库加载,再设断点
核心动作就两步:运行起来,等库加载完成。不能跳过这一步直接设断点。
- 用
run启动程序(哪怕只是跑几毫秒),触发动态链接器加载所有依赖库 - 立刻执行
info sharedlibrary,确认目标库已显示Yes(表示符号已读入) - 如果库显示
No,说明符号表没加载,此时要手动补救:sharedlibrary libmylib.so - 确保
LD_LIBRARY_PATH或solib-search-path已设对,否则 GDB 找不到库文件本身:set solib-search-path /path/to/your/libs
break 命令的三种可靠写法
别只依赖函数名裸写。动态库函数容易重名或未导出,优先用带限定的方式:
-
break libmylib.so:my_func—— 最推荐,明确指定库+函数,GDB 会自动匹配符号(即使函数在多个库中存在) -
break my_func—— 仅在info sharedlibrary确认该库已加载且符号可用后才稳妥 -
break *0x7ffff7bc1234—— 如果你知道函数地址(比如从objdump -T libmylib.so | grep my_func得到),可绕过符号解析直接下断点
注意:break 后跟文件名+行号(如 break mylib.c:42)只在你有源码且编译时加了 -g、且 GDB 能定位到源文件路径时才有效。
遇到 pending 断点别慌,这是正常机制
如果你在程序还没运行时就执行 break my_func,GDB 会提示 Breakpoint X (my_func) pending。这不是错误,而是 GDB 的延迟断点机制在起作用——它把断点记下来,等后续动态库加载并读取符号表后,自动尝试解析并启用。
- 只要最终
info breakpoints显示状态为enabled且地址非零,就说明已成功绑定 - 如果一直卡在
pending,大概率是库没加载、符号缺失(没编译进.so)、或函数名拼错(比如 C++ 名字修饰后叫_Z7my_funcv) - 检查函数是否真的导出了:
nm -D libmylib.so | grep my_func;没输出说明该函数未出现在动态符号表里,break必然失败
最易被忽略的一点:动态库必须用 gcc -g -fPIC -shared 编译,缺 -g 就没有调试符号,GDB 再怎么努力也找不到源码行和变量名。











