必须加 -g 编译,否则 GDB 无法加载符号表,导致 list 报“No symbol table”、print 报“Can’t find symbol”;调试需用 -O0 关闭优化,多线程崩溃时应配合 info threads 与 thread apply all bt 全面分析。

必须先编译带 -g 的可执行文件,否则 GDB 启动后看不到源码、变量名和行号
启动前最关键的一步:编译时加 -g
很多问题其实卡在这一步——GDB 启动成功了,但 list 显示空,print var 报 No symbol "var" in current context。根本原因就是没加调试信息。
- 正确编译:
gcc -g main.c -o main或g++ -g main.cpp -o main - 错误示范:
gcc main.c -o main(没-g,GDB 无法关联源码) - 验证是否含调试符号:
file main输出里应含with debug_info;或用readelf -w main | head -n5看是否有 DWARF 段
三种常用启动方式及适用场景
选哪种取决于你当前有没有程序、要不要传参、是不是在追线上问题:
-
gdb ./main:最基础,适合无参数、刚写完的测试程序 -
gdb --args ./main arg1 "arg two":推荐用于带参数的程序,避免进 GDB 后再输set args;注意引号会被 shell 解析,不是 GDB 解析 -
gdb -p:生产环境出问题时用,比如进程卡死或 CPU 飙高,先PIDps aux | grep myapp找 PID,再 attach 上去;需有对应权限(通常是同一用户或 root)
run 和 set args 的配合陷阱
很多人以为 gdb ./main 启动后直接 run 就能跑起来,结果报错或行为异常——因为参数没设对。
-
run不带参数 = 以空参数列表启动程序(等价于./main) -
run arg1 arg2是临时覆盖,只对本次生效;下次run还是空参数 - 要持久化参数,必须用
set args arg1 "arg two",之后每次run都会带这些参数 - 常见坑:
set args后忘记run,或者run时又手抖多打了参数,导致程序解析错乱
启动失败的典型错误信号
启动后一运行就崩?先看 GDB 输出的第一行提示:
-
Program received signal SIGSEGV, Segmentation fault.:说明程序本身有内存访问错误,不是 GDB 启动问题,而是代码 bug -
Starting program: ./main failed.: Permission denied:文件没执行权限,chmod +x ./main -
Don't know how to run. Try "help target".:GDB 没加载任何程序,可能误输gdb回车后没执行file ./main -
During startup program exited with code 127:动态链接库缺失,用ldd ./main检查依赖
真正容易被忽略的是:GDB 启动本身不检查程序是否能正常运行,它只管加载和控制。哪怕程序一启动就 exit(1),GDB 也认为“启动成功”——你得靠 run 才知道它到底干了啥。











