title: gdb调试 type: raw created: 2026-08-31
gdb(GNU Debugger)是GNU项目中的标准调试器,是Linux/Unix系统下C/C++程序调试的核心工具。它是一个命令行调试工具,支持:
使用gcc/g++编译时必须添加 -g 选项生成调试信息:
# 基本用法
gcc -g -o program program.c
# 优化编译(调试时建议关闭优化)
gcc -g -O0 -o program program.c
# C++编译
g++ -g -o program program.cpp
注意:调试时建议使用 -O0 禁用优化,否则变量可能被优化掉,无法正常调试。
# 启动并加载程序
gdb ./program
# 启动后加载已有程序
gdb
(gdb) file ./program
# 使用 --args 传递命令行参数
gdb --args ./program arg1 arg2
# 或在gdb内使用 set args
gdb ./program
(gdb) set args arg1 arg2
gdb ./program core
| 命令 | 简写 | 说明 |
|---|---|---|
run |
r |
运行程序(可带参数) |
start |
- | 运行到main函数暂停 |
continue |
c |
继续运行,直到下一个断点 |
kill |
k |
终止当前程序 |
quit |
q |
退出gdb |
(gdb) run
(gdb) run arg1 arg2
(gdb) start
(gdb) continue
| 命令 | 简写 | 说明 |
|---|---|---|
break 行号 |
b 行号 |
在指定行设断点 |
break 函数名 |
b 函数名 |
在函数入口设断点 |
break 文件:行号 |
b 文件:行号 |
在指定文件的行设断点 |
break ... if 条件 |
- | 条件断点 |
info breakpoints |
i b |
查看所有断点 |
delete 断点号 |
d 断点号 |
删除断点 |
disable 断点号 |
dis 断点号 |
禁用断点 |
enable 断点号 |
en 断点号 |
启用断点 |
# 在第10行设断点
(gdb) break 10
# 在函数main设断点
(gdb) break main
# 条件断点:当i==5时中断
(gdb) break 15 if i==5
# 查看断点
(gdb) info breakpoints
| 命令 | 简写 | 说明 |
|---|---|---|
next |
n |
单步执行,不进入函数内部 |
step |
s |
单步执行,进入函数内部 |
finish |
fin |
执行到当前函数返回 |
until 行号 |
u 行号 |
执行到指定行 |
(gdb) next # 执行下一行,跳过函数
(gdb) step # 执行下一行,进入函数
(gdb) finish # 执行到当前函数返回
(gdb) until 20 # 执行到第20行
| 命令 | 简写 | 说明 |
|---|---|---|
print 表达式 |
p 表达式 |
打印变量/表达式值 |
print *指针 |
p *指针 |
打印指针指向的内容 |
display 表达式 |
- | 每次暂停时自动打印 |
info locals |
i locals |
查看所有局部变量 |
info args |
i args |
查看函数参数 |
backtrace |
bt |
查看调用栈 |
backtrace full |
bt full |
查看调用栈及局部变量 |
list |
l |
查看源代码(当前行前后10行) |
(gdb) print variable
(gdb) print *ptr
(gdb) print arr[0]
(gdb) print sizeof(arr)
(gdb) backtrace
# #0 func1 () at test.c:10
# #1 0x0000555555555149 in main () at test.c:20
(gdb) info locals
(gdb) list 5,15 # 显示第5-15行
# 当变量值变化时中断
(gdb) watch variable
# 当变量被读取时中断
(gdb) rwatch variable
# 当变量被读或写时中断
(gdb) awatch variable
# 查看观察点
(gdb) info watchpoints
# 查看所有线程
(gdb) info threads
# Id Target Id Frame
# * 1 Thread 0x7ffff... main () at test.c:10
# 2 Thread 0x7fff8... 0x00007ffff... in pthread_join ()
# 切换到指定线程
(gdb) thread 2
# 为所有线程设断点
(gdb) thread apply all bt
# 在特定线程执行命令
(gdb) thread apply 1-3 print variable
# 查看当前限制
ulimit -c
# 开启core dump(无大小限制)
ulimit -c unlimited
# 设置core文件名格式(可选)
echo "/tmp/core.%e.%p" > /proc/sys/kernel/core_pattern
# 使用gdb分析
gdb ./program core
# 或使用coredumpctl(systemd系统)
coredumpctl list
coredumpctl gdb PID
(gdb) bt # 查看崩溃时调用栈
(gdb) bt full # 包含局部变量
(gdb) info registers # 查看寄存器
(gdb) frame N # 切换到第N层栈帧
(gdb) print variable # 查看变量值
Host (开发机) Target (目标板)
+-----------+ +-----------+
| gdb | <--- TCP/串口 ---> | gdbserver |
+-----------+ +-----------+
|
program
# 目标板启动gdbserver
gdbserver :1234 ./program
# 或使用串口
gdbserver /dev/ttyS0 ./program
# 启动gdb
gdb ./program
# 连接目标板
(gdb) target remote 192.168.1.100:1234
# 或串口
(gdb) target remote /dev/ttyUSB0
# 然后正常调试
(gdb) break main
(gdb) run
(gdb) continue
# 交叉编译带调试信息
arm-linux-gnueabihf-gcc -g -o program program.c
# 使用交叉gdb
arm-linux-gnueabihf-gdb ./program
(gdb) target remote 192.168.1.100:1234
# 启动TUI模式
gdb -tui ./program
# 在gdb内切换
(gdb) layout src # 显示源代码窗口
(gdb) layout asm # 显示汇编窗口
(gdb) layout regs # 显示寄存器
(gdb) focus cmd # 切换焦点到命令窗口
# 查看宏定义
(gdb) macro expand MACRO_NAME
# 查看所有宏
(gdb) info macros
# 忽略前N次命中
(gdb) ignore 1 10 # 断点1忽略前10次
# 命中断点时执行命令
(gdb) commands 1
> print variable
> continue
> end
# 如果必须调试优化代码
gcc -g -O1 -o program program.c
# gdb中查看优化掉的变量
(gdb) info optimization
# 打印数组所有元素
(gdb) p arr@10 # 打印arr[0]到arr[9]
# 修改变量值
(gdb) set variable = 100
# 调用函数
(gdb) call func(arg)
# 显示内存
(gdb) x/20xw 0x7fffffffe000 # 显示20个4字节十六进制值
-g 编译,否则无法单步调试-O2/-O3 优化会导致代码顺序变化,调试困难YAMA或具有CAP_SYS_PTRACEgdb如何调试段错误?
如何调试多线程程序?
info threads查看线程,thread N切换,thread apply批量操作如何调试内存泄漏?
gdb和Valgrind的区别?
如何调试release版本?
-g),或使用addr2line将地址转为源码行号条件断点的作用?
# 崩溃分析三板斧
gdb ./program core
(gdb) bt
(gdb) print variable
(gdb) info registers
# 悬空指针调试
(gdb) watch *ptr
(gdb) continue
# 查看系统调用
(gdb) catch syscall
本文件用于知识归档,内容可直接用于学习与复习。