Grok生成(2025年11月3日22:52:04)
目录
- GDB 与 CGDB 学习文档
- 前言:为什么要学习 GDB 和 CGDB?
- 目录
- 1. 环境准备
- 安装工具
- 验证安装
- 2. 编译时必须加
-g!(最容易忽略的点) - 3. GDB 基础命令(背会这 15 个就够用 80%)
- 4. CGDB 安装与界面详解
- 启动 CGDB
- CGDB 界面划分(分屏)
- 关键快捷键(比 GDB 好用 10 倍!)
- 5. CGDB 实战演练(带示例代码)
- 示例代码:
bug.c - 编译
- 启动 CGDB
- 操作步骤(跟着做!)
- 示例代码:
- 6. 常见调试场景
- 场景1:程序崩溃(Segmentation fault)
- 场景2:循环没停(死循环)
- 场景3:条件断点(只在 i==3 时停)
- 7. 高级技巧(进阶必备)
- 8. 练习题(动手做!)
- 练习1:数组越界
- 练习2:死循环
- 练习3:条件断点
- 9. 资源推荐
- 总结:你的调试流程(贴在桌边!)
GDB 与 CGDB 学习文档
—— 专为初学者设计,中文详细讲解,易懂易上手
前言:为什么要学习 GDB 和 CGDB?
调试(Debugging)是程序员的“侦探工作”。
当程序崩溃、结果不对、卡死时,GDB(GNU Debugger)是 Linux 下最强大的“放大镜”,能让你:
- 看到程序每一步在做什么
- 查看变量值
- 找到崩溃位置
- 控制程序暂停、继续、单步执行
而 CGDB 是 GDB 的“可视化皮肤”,像 IDE 一样有:
- 代码高亮
- 分屏显示源码
- 键盘操作更友好
本教程目标:让你 3 天内从“完全不会”到“能用 GDB/CGDB 调试简单 C/C++ 程序”。
目录
- 环境准备
- GDB 基础命令(核心!)
- 编译时加调试信息(必须!)
- CGDB 安装与界面详解
- CGDB 实战操作(带图解)
- 常见调试场景(崩溃、断点、条件断点)
- 高级技巧(watch、backtrace、frame)
- 练习题(必做!)
- 资源推荐
1. 环境准备
安装工具
# Ubuntu/Debian
sudo apt update
sudo apt install gdb cgdb build-essential# CentOS/RHEL
sudo yum install gdb cgdb gcc gcc-c++# Arch Linux
sudo pacman -S gdb cgdb gcc
验证安装
gdb --version # 应该显示版本号
cgdb --version
2. 编译时必须加 -g!(最容易忽略的点)
# 错误示范(没有调试信息)
gcc main.c -o app# 正确示范(加上 -g)
gcc -g main.c -o app # 调试用
gcc -g -O0 main.c -o app # 推荐:关闭优化,更好调试
记住:不加
-g,GDB 看不到源码和变量!
3. GDB 基础命令(背会这 15 个就够用 80%)
| 命令 | 含义 | 示例 |
|---|---|---|
gdb ./app |
启动 GDB 调试程序 | gdb ./app |
r 或 run |
运行程序 | r |
r arg1 arg2 |
带参数运行 | r 10 20 |
b 行号 |
在某行设置断点 | b 15 |
b 函数名 |
在函数入口断点 | b main |
c 或 continue |
继续运行到下一个断点 | c |
n 或 next |
单步执行(不进入函数) | n |
s 或 step |
单步执行(进入函数) | s |
p 变量 或 print |
打印变量值 | p i |
p 数组[0]@5 |
打印数组前5个元素 | p arr[0]@5 |
bt 或 backtrace |
查看调用栈 | bt |
f 编号 或 frame |
切换到某层栈帧 | f 2 |
l 或 list |
显示当前源码 | l |
info breakpoints |
查看所有断点 | info b |
d 断点号 或 delete |
删除断点 | d 1 |
q 或 quit |
退出 GDB | q |
4. CGDB 安装与界面详解
启动 CGDB
cgdb ./app
CGDB 界面划分(分屏)
┌─────────────────────────────────────────────┐
│ [CGDB 标题栏] │
├─────────────┬───────────────────────────────┤
│ │ │
│ 源码窗口 │ GDB 命令窗口 │
│ (高亮显示) │ > (gdb) │
│ │ │
└─────────────┴───────────────────────────────┘
关键快捷键(比 GDB 好用 10 倍!)
| 按键 | 功能 |
|---|---|
Esc |
切换到 源码窗口(可上下翻代码) |
i |
切换到 GDB 命令窗口(输入命令) |
Ctrl + L |
刷新屏幕 |
F5 |
相当于 run |
F6 |
相当于 continue |
F7 |
相当于 step(进入函数) |
F8 |
相当于 next(不进入) |
PageUp / PageDown |
翻页看源码 |
o |
在源码窗口跳到当前执行行 |
Ctrl + T |
显示 TUI 模式(类似 gdb 的 layout) |
5. CGDB 实战演练(带示例代码)
示例代码:bug.c
#include <stdio.h>int add(int a, int b) {int c = a + b;return c;
}int main() {int i;int arr[5] = {1, 2, 3, 4, 5};for(i = 0; i <= 5; i++) { // 故意越界!printf("arr[%d] = %d\n", i, arr[i]);}int sum = add(10, 20);printf("sum = %d\n", sum);return 0;
}
编译
gcc -g -O0 bug.c -o bug
启动 CGDB
cgdb ./bug
操作步骤(跟着做!)
- 启动后按
i进入 GDB 窗口 - 输入:
b main r - 程序停在
main第一行
→ 按Esc切换到源码窗口,上下键翻代码 - 设置断点:
b 12 # 在 for 循环那行 - 按
F6(continue)运行到断点 - 按
F7(step)单步执行,观察i变化 - 打印变量:
p i p arr[0]@5 - 程序崩溃时(段错误),输入:
bt # 看调用栈
6. 常见调试场景
场景1:程序崩溃(Segmentation fault)
(gdb) r
# 崩溃
(gdb) bt
# 查看是哪一行
(gdb) f 0
(gdb) l # 看当前行
场景2:循环没停(死循环)
b 循环行
c
# 停下后
p 变量名
# 改值测试
set var i = 100
c
场景3:条件断点(只在 i==3 时停)
b 12 if i == 3
7. 高级技巧(进阶必备)
| 命令 | 用途 |
|---|---|
watch x |
当变量 x 被修改时暂停 |
rwatch x |
当变量 x 被读取时暂停 |
awatch x |
读或写都暂停 |
display i |
每次停下都自动显示 i 的值 |
undisplay 1 |
取消 display |
info locals |
查看当前函数所有局部变量 |
info args |
查看当前函数参数 |
thread apply all bt |
多线程程序:查看所有线程栈 |
8. 练习题(动手做!)
练习1:数组越界
用上面的 bug.c,用 CGDB 找到越界位置,并用 p arr[5] 验证。
练习2:死循环
写一个死循环:
int i = 0;
while(1) {printf("%d\n", i++);if(i > 100000) break; // 故意写错条件
}
用 watch i 监控 i,改值跳出循环。
练习3:条件断点
在数组遍历中,只在 i == 2 时打印 arr[i]。
9. 资源推荐
| 资源 | 链接 |
|---|---|
| GDB 官方手册 | https://sourceware.org/gdb/current/onlinedocs/gdb/ |
| CGDB 官网 | https://cgdb.github.io/ |
| GDB 速查卡 | 搜索 “GDB cheat sheet” |
| 视频教程 | B站搜索 “GDB 调试教程” |
总结:你的调试流程(贴在桌边!)
1. gcc -g -O0 xxx.c -o xxx
2. cgdb ./xxx
3. b main → r
4. 用 F5/F6/F7/F8 控制流程
5. p 变量 / bt 查看
6. 改值 → set var x = 100
7. 继续 → c