GDB 调试常用命令速查
更新时间:2026-09-20。问题驱动短答页。GDB 是 Linux/C/C++/Rust 下最核心的调试器,也是排查段错误、死锁、core dump 的主力。工具主页见 gdb,实战见 GDB 调试、GDB 反汇编。
前置:带调试信息编译
bash
gcc -g -O0 main.c -o main # -g 加符号行号,-O0 关闭优化避免变量被优化掉
gdb ./main # 启动
gdb ./main core # 带 core 文件做事后分析启动与运行
| 命令 | 作用 |
|---|---|
run(r) | 跑程序,可带参数 run arg1 arg2 |
start | 在 main 入口自动断下 |
break main.c:42(b) | 按文件:行号下断 |
b func | 函数入口断点 |
b f.c:10 if x==5 | 条件断点 |
delete N/disable N/enable N | 删除/禁用/启用断点 |
continue(c) | 继续运行 |
quit(q) | 退出 |
单步与栈
| 命令 | 作用 |
|---|---|
next(n) | 单步步过(不进入函数) |
step(s) | 单步步入(进入函数) |
finish | 运行到当前函数返回 |
until 30(u) | 运行到第 30 行(跳出循环好用) |
backtrace(bt) | 打印调用栈(bt full 带局部变量) |
frame N(f N) | 切到第 N 层栈帧 |
up/down | 在栈帧间上下移动 |
查看数据
gdb
print x # 打印变量;p *ptr@10 连续看 10 个元素
print/x buf # 按十六进制;/d 十进制 /t 二进制 /c 字符
display i # 每次停下自动打印 i
info locals # 当前栈帧所有局部变量
info args # 函数参数
x/16xb buf # 查看内存:16 个、hex、byte
watch counter # 数据断点,counter 被改写时断下watch(硬件观察点)排查「某个变量/内存被谁偷偷改了」极其有效;rwatch/awatch 分别在读/读写时断。
多线程
| 命令 | 作用 |
|---|---|
info threads | 列出所有线程 |
thread N | 切到线程 N |
thread apply all bt | 打印所有线程调用栈(查死锁首选) |
set scheduler-locking on | 单步时只跑当前线程,避免乱跑 |
b f.c:8 thread 3 | 只在线程 3 下断 |
core dump 事后调试
bash
ulimit -c unlimited # 允许生成 core
gdb ./app core.1234 # 加载
(gdb) bt # 崩溃栈;frame N 再看变量段错误定位完整流程见段错误怎么排查 与 core dump 调试。
界面与小技巧
layout src:上方显示源码的 TUI 界面(Ctrl-X A退出,Ctrl-L刷屏);layout split同时看汇编。set pagination off:输出不分页;set print pretty on:结构体美化。gdb -p <pid>:attach 到正在运行的进程,detach脱离。
常见坑
- 没加
-g:栈里只有地址没有函数名/行号,重新带-g编译。 -O2下变量显示 optimized out、跳转乱跳:调试用-O0。next/step分不清:step 会进入被调函数,next 当成一条语句跨过。- 多线程断点被别的线程反复命中:用条件断点或
scheduler-locking。 - core 文件为空/不生成:
ulimit -c为 0 或 core_pattern 被改,先放开并查/proc/sys/kernel/core_pattern。 - C++ 函数名被 name-mangling:断点可写
b 'Class::method'或用rbreak正则。
总结
用 gdb 前先以 -g -O0 编译拿到行号与变量;核心套路是 break 下断(支持条件断点)、run/start 启动、next 步过/step 步入/finish 跑完函数、backtrace 看调用栈、frame 切换、print/display/x 看变量内存、watch 监视被改写内存;多线程用 info threads、thread apply all bt 一键抓死锁并配 scheduler-locking;事后用 gdb ./app core 加 bt 分析崩溃,没符号或高优化是最常见的两个坑。