工程化

GDB 调试 C 程序完全指南

GDB 是 Linux 下最经典的 C/C++ 调试器。掌握它的核心命令,能大幅提升定位段错误、死循环与逻辑 bug 的效率。本文覆盖日常调试中最常用的操作。

一、编译时开启调试信息

使用 -g 选项保留符号表,GDB 才能将机器码映射回源代码行号与变量名:

gcc -g -O0 hello.c -o hello
/* -O0 关闭优化,避免变量被优化掉导致无法观察 */

二、启动与基本命令

gdb ./hello          /* 启动调试器 */
run                  /* 运行程序(可带参数) */
quit                 /* 退出 GDB */

三、断点管理

断点让程序在指定位置暂停,是调试的核心手段:

break main           /* 在 main 函数入口设断点 */
break hello.c:25     /* 在第 25 行设断点 */
break foo if i==5    /* 条件断点:仅当 i==5 时停下 */
info breakpoints     /* 查看所有断点 */
delete 2             /* 删除编号为 2 的断点 */
disable 1            /* 临时禁用断点 */
条件断点在循环中非常有用,避免手动重复 continue。

四、单步执行

next    (n)          /* 执行下一行(不进入函数内部) */
step    (s)          /* 执行下一行(进入函数内部) */
finish               /* 执行完当前函数并返回 */
continue (c)         /* 继续运行直到下一个断点 */
until                /* 运行到当前循环结束 */

五、查看状态

print x              /* 打印变量 x 的值 */
print *ptr@10        /* 打印指针指向的前 10 个元素 */
display x            /* 每次停下自动打印 x */
info locals          /* 查看所有局部变量 */
info args            /* 查看函数参数 */

六、栈帧回溯

段错误发生时,第一件事就是查看调用栈:

backtrace (bt)       /* 显示完整调用栈 */
bt full              /* 同时显示每个栈帧的局部变量 */
frame 2              /* 切换到第 2 层栈帧 */
up / down            /* 在栈帧间上下移动 */
段错误后 GDB 会自动停下,此时立即执行 bt 即可定位崩溃位置。

七、Core Dump 事后分析

程序崩溃后若生成了 core 文件,可离线分析:

/* 1. 开启 core 文件生成 */
ulimit -c unlimited

/* 2. 崩溃后得到 core 文件 */
gdb ./hello core

/* 3. 进入后直接 bt 查看崩溃现场 */
(gdb) bt
#0  0x000... in foo (p=0x0) at hello.c:42
#1  0x000... in main () at hello.c:15

八、常用命令速查表

  • l — list,显示源代码
  • b — break,设置断点
  • c — continue,继续运行
  • n — next,单步跳过
  • s — step,单步进入
  • p — print,打印变量
  • q — quit,退出
在 GDB 中直接按回车会重复上一条命令,单步时非常方便。