GDB调试工具
GDB(GNU Debugger)是Linux平台上最强大的调试工具。掌握GDB,能够大幅提高调试效率,快速定位程序bug。本文将系统讲解GDB的使用方法和实战技巧。
一、GDB基础
1.1 编译调试版本
使用-g选项编译程序:
bash
gcc -g -O0 program.c -o program
-g:生成调试信息-O0:关闭优化(O是字母O,数字0)
1.2 启动GDB
方式1:直接启动
bash
gdb ./program
方式2:附加到运行中的进程
bash
gdb attach <pid>
方式3:分析core文件
bash
gdb ./program core
1.3 GDB基本命令
| 命令 | 简写 | 说明 |
|---|---|---|
| run | r | 运行程序 |
| break | b | 设置断点 |
| next | n | 单步执行(不进入函数) |
| step | s | 单步执行(进入函数) |
| continue | c | 继续执行 |
| p | 打印变量值 | |
| list | l | 显示源代码 |
| quit | q | 退出GDB |
二、断点管理
2.1 设置断点
bash
# 在函数处设置断点
(gdb) break main
(gdb) b my_function
# 在指定行设置断点
(gdb) break 20
(gdb) break file.c:20
# 条件断点
(gdb) break 20 if i == 5
(gdb) b main.c:30 if x > 10
# 查看断点信息
(gdb) info break
(gdb) i b
# 删除断点
(gdb) delete 1 # 删除1号断点
(gdb) d 1-5 # 删除1到5号断点
# 禁用/启用断点
(gdb) disable 1
(gdb) enable 1
2.2 观察点(Watchpoint)
bash
# 监视变量变化
(gdb) watch x # x值改变时停止
(gdb) rwatch x # x被读取时停止
(gdb) awatch x # x被读取或写入时停止
# 查看观察点
(gdb) info watch
三、程序控制
3.1 执行控制
bash
# 运行程序
(gdb) run
(gdb) r arg1 arg2 # 带参数运行
# 单步执行
(gdb) next # 下一步(不进入函数)
(gdb) n
(gdb) step # 下一步(进入函数)
(gdb) s
# 继续执行
(gdb) continue # 运行到下一个断点
(gdb) c
# 执行到指定位置
(gdb) until 30 # 执行到第30行
(gdb) u 30
# 跳出当前函数
(gdb) finish
# 执行到函数末尾
(gdb) return # 立即返回
(gdb) return 100 # 返回指定值
3.2 查看源代码
bash
# 显示源代码
(gdb) list
(gdb) l
# 显示指定范围
(gdb) list 10,20
# 显示指定函数
(gdb) list main
# 显示其他文件
(gdb) list file.c:main
四、变量检查
4.1 打印变量
bash
# 打印变量值
(gdb) print x
(gdb) p/x x # 十六进制
(gdb) p/d x # 十进制
(gdb) p/c x # 字符
# 打印数组
(gdb) print arr[0]@10 # 打印arr的前10个元素
(gdb) p *arr@10
# 打印结构体
(gdb) print *ptr
(gdb) p ptr->member
# 打印字符串
(gdb) print str
(gdb) p/s str
# 打印内存
(gdb) x/10xw &var # 查看var开始的10个字
4.2 显示类型
bash
# 查看变量类型
(gdb) whatis x
# 查看详细类型
(gdb) ptype struct_name
4.3 自动显示
bash
# 每次停止时自动显示
(gdb) display x
(gdb) display/i $pc # 显示当前指令
# 查看display列表
(gdb) info display
# 删除display
(gdb) undisplay 1
五、栈帧管理
5.1 查看调用栈
bash
# 显示调用栈
(gdb) backtrace
(gdb) bt
(gdb) bt 5 # 只显示5层
# 切换栈帧
(gdb) frame 2 # 切换到第2帧
(gdb) f 2
# 查看当前帧信息
(gdb) info frame
(gdb) info locals # 查看局部变量
(gdb) info args # 查看函数参数
六、高级调试
6.1 多线程调试
bash
# 查看所有线程
(gdb) info threads
# 切换线程
(gdb) thread 2
# 在所有线程设置断点
(gdb) set scheduler-locking on # 只让当前线程运行
(gdb) set scheduler-locking off # 所有线程运行
6.2 内存检查
bash
# 检查内存泄漏(需要valgrind)
valgrind --leak-check=full ./program
# GDB内存检查
(gdb) x/20xw 0x7fffffffdc00 # 查看内存
6.3 Core文件分析
bash
# 开启core文件生成
ulimit -c unlimited
# 程序崩溃后生成core文件
./program
# 分析core文件
gdb ./program core
# 在GDB中查看崩溃位置
(gdb) bt
(gdb) frame 0
(gdb) info locals
七、实用技巧
7.1 命令历史
bash
# 查看历史命令
(gdb) show commands
# 使用历史命令
(gdb) !10 # 执行第10条历史命令
7.2 日志记录
bash
# 开启日志
(gdb) set logging on
(gdb) set logging file gdb.log
7.3 自定义命令
gdb
# 定义快捷命令
define plist
set $node = $arg0
while $node
print *$node
set $node = $node->next
end
end
八、常见调试场景
8.1 段错误调试
bash
# 方法1:使用core文件
ulimit -c unlimited
./program
gdb ./program core
(gdb) bt
# 方法2:直接运行
gdb ./program
(gdb) run
# 程序崩溃后
(gdb) bt
(gdb) frame 0
8.2 死循环定位
bash
gdb ./program
(gdb) run
# 程序卡住时按Ctrl+C
(gdb) bt
(gdb) info locals
8.3 变量值异常
bash
# 使用条件断点
(gdb) break 30 if x < 0
(gdb) run
# 触发断点后检查相关变量
(gdb) print x
(gdb) bt
九、总结
GDB是Linux调试的利器:
- 基本操作:run、break、next、step、continue
- 变量检查:print、display、whatis
- 栈管理:backtrace、frame
- 高级功能:多线程、core分析
调试技巧:
- 善用条件断点
- 使用watch监视变量
- 配合core文件定位崩溃
- 多线程调试使用scheduler-locking