一、先把编译方式弄对
程序一般有两种发布方式:debug 和 release。
debug 版本会带上调试信息,断点、单步、查看变量这些操作才有意义;release 版本通常会把这些信息去掉,文件更小,但调试器基本就没法正常工作了。
Linux 下用 gcc / g++ 编译时,如果你习惯写成 gcc -o $@ $^,默认得到的就是偏 release 的结果。真要调试,得加上 -g:
gcc -o $@ $^ -g
这一步很基础,但经常被忽略。程序跑不进断点,先别急着怀疑 gdb,先看是不是编译参数就不对。
二、启动 gdb / cgdb
先确认系统里已经装了 gdb 或 cgdb,然后再打开目标程序:
gdb 文件名
退出调试可以按 Ctrl+D,或者输入 quit 回车。
刚进 gdb 时通常看不到源码,得先用 list 相关命令把代码拉出来:
l:显示源代码,每次 10 行l 函数名或l 文件名:查看指定函数或文件l 文件名:行号:查看指定文件某一行附近的代码
纯 gdb 这样用没问题,但来回敲命令看代码确实有点累。cgdb 就是把源码窗口直接摆出来,其他调试命令还是 gdb 那套。日常排查时我更愿意用它,省得上下翻命令历史。
后面的命令,按 cgdb 的习惯来讲。
三、常用调试命令
1. 运行、断点、继续执行
r/run:开始运行程序;如果程序已经跑过,也可以重新从头运行b [文件名:]行号:在指定行设置断点info b:查看当前所有断点d:删除所有断点d 断点序号:删除指定断点c/continue:继续执行到下一个断点n/next:单步执行,不进入函数内部s/step:单步执行,遇到函数就进入内部f/finish:运行到当前函数返回until 行号:执行到指定行
断点会在对应行上显示出来。每个断点都有自己的序号,info b 里能看到。删断点时用的是序号,不是行号,这点很容易搞混。
在 gdb / cgdb 里直接回车,会重复执行上一条命令。
2. 查看和修改变量
调试时最常看的还是变量:
p 变量或p 表达式:打印变量或表达式的值set var 变量 = 值:修改变量值display 变量:持续显示变量值undisplay 变量序号:取消持续显示watch 变量:监视变量,一旦值发生变化,程序会停下来


