GDB调试工具详解
GDB调试工具详解
一、基本概念
- 调试信息
编译时需添加-g
选项(如gcc -g -o program program.c
),生成包含变量名、函数名、行号等调试信息的可执行文件。 - 断点(Breakpoint)
程序执行到指定位置(函数、行号)时暂停,用于观察程序状态。 - 单步执行(Stepping)
next
: 逐行执行(不进入函数内部)。step
: 逐行执行(进入函数内部)。
- 调用栈(Call Stack)
显示函数调用层次关系,帮助定位问题根源。
二、启动GDB
1. 调试可执行文件
gdb ./your_program
2. 附加到运行中的进程
gdb -p <PID>
3. 分析核心转储文件
gdb ./your_program core
三、常用命令
1. 运行程序
命令 | 说明 |
---|---|
run [args] | 启动程序并传入参数(如 run arg1 arg2 ) |
start | 启动程序并在 main 函数入口暂停 |
2. 断点管理
命令 | 说明 |
---|---|
break main 或 b 20 | 在函数/行号处设置断点 |
break test.c:15 if x==5 | 条件断点(当 x=5 时触发) |
info breakpoints | 查看所有断点信息 |
delete 1 | 删除编号为1的断点 |
3. 单步执行
命令 | 说明 |
---|---|
next (n) | 执行下一行(跳过函数调用) |
step (s) | 执行下一行(进入函数内部) |
finish | 执行完当前函数并暂停 |
4. 查看变量与内存
命令 | 说明 |
---|---|
print x | 打印变量值 |
x/8xb &var | 以十六进制查看变量内存(显示8字节) |
set var x=10 | 修改变量值 |
5. 调用栈操作
命令 | 说明 |
---|---|
backtrace (bt) | 查看当前调用栈 |
frame 2 | 切换到调用栈第2层 |
6. 退出GDB
(gdb) quit
四、高级功能
1. 观察点(Watchpoints)
(gdb) watch x # 当变量x被修改时暂停
(gdb) watch (x > 10) # 监视表达式
2. 多线程调试
命令 | 说明 |
---|---|
info threads | 查看所有线程 |
thread 3 | 切换到线程3 |
set scheduler-locking step | 调试时锁定其他线程 |
3. 核心转储分析
-
生成核心转储文件:
ulimit -c unlimited ./your_program
-
分析核心文件:
gdb ./your_program core
4. 自动化调试
-
自定义命令:在
~/.gdbinit
中定义快捷命令:define mycmdinfo registersbacktrace end
-
脚本调试:将命令写入
script.gdb
,通过gdb -x script.gdb
执行。
五、调试示例
示例代码(test.c
)
#include <stdio.h>int add(int a, int b) {int result = a + b;return result;
}int main() {int x = 3, y = 5;int sum = add(x, y);printf("Sum: %d\n", sum);return 0;
}
调试步骤
-
编译程序:
gcc -g -o test test.c
-
启动GDB:
gdb test
-
设置断点:
(gdb) break add
-
运行程序:
(gdb) run
-
查看变量:
(gdb) print x # 输出 3 (gdb) print y # 输出 5
-
单步执行:
(gdb) next # 执行到 return result
六、常见问题
- 断点不生效
- 确保编译时添加
-g
选项。 - 检查代码路径与实际程序是否一致。
- 确保编译时添加
- 变量显示
<optimized out>
- 编译时禁用优化:
gcc -O0 -g ...
- 编译时禁用优化:
- 多线程调试混乱
- 使用
set scheduler-locking on
限制线程调度。
- 使用
七、总结
GDB通过断点、单步执行、变量监控等功能,帮助开发者高效定位代码逻辑错误、内存问题及多线程问题。