2. GDB基本命令:run、break、next、step、continue、print、quit、list命令详解

调试C/C++程序,说白了就是跟代码的「灵魂」对话。而GDB,就是那个翻译官。我刚开始用GDB时,其实就靠七八个命令活下来的。今天咱们就把这几个核心命令掰开揉碎,讲透它。

核心思想:GDB调试的本质是「控制执行流 + 观察状态」。run负责启动,break设断点,next/step控制步进,continue恢复运行,print看变量,list读源码,quit收工。就这么简单。

2.1 run —— 让程序跑起来

run(简写r)是启动程序的命令。你想想看,没有它,后面所有命令都是空谈。

(gdb) run
(gdb) r              # 简写形式
(gdb) run arg1 arg2  # 带命令行参数启动
(gdb) run < input.txt # 重定向输入

我在项目中遇到过一个问题:程序启动时需要加载一个几百MB的配置文件。每次run都要等半天。后来我发现,可以用set args提前设置参数,然后直接run就行。

小技巧:如果程序已经跑过一次,再次run时GDB会问你是否重启。用y确认就行。我个人习惯直接敲r,省事。

2.2 break —— 让程序停下来

break(简写b)是断点命令。没有断点,程序就像脱缰的野马,你根本抓不住它。

(gdb) break main              # 在main函数入口设断点
(gdb) b 42                    # 在当前文件第42行设断点
(gdb) b foo.c:100             # 在foo.c第100行设断点
(gdb) b my_function           # 在函数my_function入口设断点
(gdb) b *0x400520             # 在内存地址0x400520设断点

嗯,这里要注意:断点可以设多个,GDB会给每个断点分配一个编号。你可以用info breakpoints查看所有断点。

避坑指南:我曾经在循环体里设了断点,结果每次循环都停一次,调试到崩溃。后来学会了用condition给断点加条件,比如condition 1 i == 100,只在i等于100时才停。这招太实用了。

2.3 next —— 一步一步走

next(简写n)是「单步跳过」命令。它会执行当前行,如果遇到函数调用,不会进入函数内部,直接执行完整个函数。

(gdb) next
(gdb) n              # 简写形式
(gdb) next 5         # 连续执行5步

为什么会这样?因为next把函数调用当作一个「黑盒」来处理。你只关心结果,不关心内部实现时,用next最合适。

2.4 step —— 钻进函数里看看

step(简写s)是「单步进入」命令。它和next的区别在于:遇到函数调用时,step会进入函数内部,一行一行地执行。

(gdb) step
(gdb) s              # 简写形式
(gdb) step 3         # 连续执行3步

我个人习惯是:调试自己写的函数用step,调试库函数用next。你想想看,要是printf这种函数你也step进去,那得看到猴年马月去。

命令 行为 适用场景
next (n) 不进入函数,直接执行完 函数逻辑已确认,只看结果
step (s) 进入函数内部,逐行执行 需要排查函数内部逻辑

2.5 continue —— 继续跑起来

continue(简写c)让程序从当前断点处继续执行,直到遇到下一个断点或程序结束。

(gdb) continue
(gdb) c              # 简写形式
(gdb) c 5            # 忽略当前断点5次,第6次才停

我记得有一次调试一个死循环,设了断点后一直c,手都按酸了。后来发现c 5可以跳过前5次命中,直接停在第6次。嗯,这功能藏得有点深,但真香。

2.6 print —— 看看变量值

print(简写p)是观察变量的命令。调试的核心就是「看变量」,没有print,你就是在盲调。

(gdb) print i                 # 打印变量i的值
(gdb) p &i                   # 打印变量i的地址
(gdb) p *ptr                 # 打印指针指向的值
(gdb) p array[5]             # 打印数组第6个元素
(gdb) p/x 0x100              # 以十六进制打印
(gdb) p/d 0x100              # 以十进制打印
(gdb) p/f 3.14               # 以浮点数打印

小技巧:GDB支持表达式计算。比如p i + j * 2,它会先计算再打印。我在项目中经常用p sizeof(struct xxx)来确认结构体大小,比翻头文件快多了。

2.7 quit —— 退出调试

quit(简写q)退出GDB。没什么好说的,但有个小细节:如果程序还在运行,GDB会问你是否要终止。用y确认就行。

(gdb) quit
(gdb) q              # 简写形式

2.8 list —— 看看源码

list(简写l)显示源代码。调试时经常需要确认当前执行到哪一行了,或者看看上下文。

(gdb) list              # 显示当前行附近的10行
(gdb) l 42              # 显示第42行附近的10行
(gdb) l main            # 显示main函数附近的代码
(gdb) l foo.c:100       # 显示foo.c第100行附近的代码
(gdb) l 1,50            # 显示第1行到第50行

我个人习惯是:每次step或next之后,先l一下看看上下文,确认自己没跑偏。你想想看,要是跑到了完全没想到的代码分支里,那调试就变成猜谜了。

核心总结:这8个命令构成了GDB调试的「最小可用集」。run启动,break设停,next/step控制步进,continue恢复,print观察,list确认位置,quit收工。把这几个练熟了,90%的调试场景你都能应付。

GDB基本命令知识体系 GDB调试核心 启动阶段 控制阶段 观察阶段 辅助阶段 收尾阶段 run (r) break (b) print (p) list (l) quit (q) next (n) step (s) continue (c) 三大阶段:启动 → 控制(设断点+步进+恢复) → 观察(打印变量) 辅助命令list看源码,quit安全退出

实战建议:把这8个命令记在脑子里,调试时手不要停。我刚开始学GDB时,把命令写在便签纸上贴在显示器边上,用了一周就烂熟于心了。你试试看,真的不难。

可可精品资料库