必须用-g编译,否则gdb报no symbol table loaded;-g生成.debug_*段供调试器识别源码、设断点,多文件需统一加-g,且gdb必须加载可执行文件而非.c源文件。

必须用 -g 编译,否则 GDB 进去就报 no symbol table loaded——这不是 GDB 的问题,是程序根本没带调试信息。
编译时漏掉 -g 就等于没装刹车
gcc 默认生成的是 Release 模式可执行文件,所有变量名、行号、函数结构全被剥离。GDB 看不到源码,也设不了断点,list 会提示 not in executable format。
-
gcc -g -o myapp myapp.c是最低要求;更推荐gcc -ggdb -O0 -o myapp myapp.c:-ggdb提供完整符号,-O0关闭优化,避免单步跳转错乱 - 多个源文件(如
main.c和utils.c)要统一加-g:gcc -g main.c utils.c -o app,不能只给其中一个加 - 用
readelf -S app | grep debug检查是否真有调试段——看到.debug_info.debug_line才算成功
启动 GDB 必须指定可执行文件,不是 .c 文件
常见错误是 gdb main.c,GDB 会报 No symbol table is loaded 或直接拒绝加载。它只能调试已编译的二进制。
- 正确命令:
gdb ./myapp或gdb myapp(当前目录下) - 如果可执行文件在别处,路径必须写全:
gdb /path/to/myapp - 想开 TUI 图形界面看代码?加
-tui:gdb -tui ./myapp,但终端宽度不够会崩,慎用
断点和单步选错命令,调试效率直接归零
n(next)和 s(step)表面只差一个字母,实际行为完全不同,选错就会跳过关键函数或卡死在库函数里。
- 用
s进入你自己写的函数(比如sum()),用n跳过标准库调用(比如printf()) - 断点设在函数名上:
b main、b calc_value;设在某行:b 23或b utils.c:45 -
info breakpoints查看断点状态,disable 1临时关掉第 1 个,比删了再重设快得多
最常被忽略的其实是编译阶段:很多人反复改 GDB 命令,却没意识到 -g 漏了、-O2 还开着、或者多文件编译时只给主文件加了调试选项——GDB 再熟也没用,它只能看程序“告诉”它的东西。











