GDB实战教学
GDB 详细使用指南:深入分析与实例演示
GDB(GNU Debugger)是Linux环境下最强大的程序调试工具,支持C/C++等多种语言。本文将全面解析其核心功能,结合实例演示和结构化说明。
一、GDB 基础操作
1. 编译与启动
# 编译时添加调试信息
gcc -g -o demo demo.c# 启动GDB
gdb ./demo
2. 基础命令速查表
命令 | 简写 | 功能 | 示例 |
---|---|---|---|
run | r | 启动程序 | run arg1 arg2 |
break | b | 设置断点 | b main |
continue | c | 继续执行 | c |
next | n | 单步执行(跳过函数) | n |
step | s | 单步执行(进入函数) | s |
print | p | 打印变量值 | p variable |
backtrace | bt | 显示调用栈 | bt |
quit | q | 退出GDB | q |
list | l | 显示源代码 | l 10 (显示第10行) |
二、断点管理(核心功能)
1. 断点类型
# 行断点
(gdb) b 20 # 当前文件第20行
(gdb) b file.c:15 # 指定文件的行# 函数断点
(gdb) b main
(gdb) b MyClass::func # C++类成员函数# 条件断点
(gdb) b 30 if count > 100# 临时断点(命中后自动删除)
(gdb) tbreak 42
2. 断点管理命令
# 查看所有断点
(gdb) info breakpoints
Num Type Disp Enb Address What
1 break keep y 0x400537 in main at demo.c:10
2 break keep y 0x400552 in foo at demo.c:20 if x>5# 禁用/启用断点
(gdb) disable 2
(gdb) enable 1# 删除断点
(gdb) delete 1 # 删除ID=1的断点
(gdb) delete # 删除所有断点
三、数据检查与修改
1. 变量查看
# 基本打印
(gdb) p variable
$1 = 42# 格式化输出
(gdb) p/x variable # 十六进制
$2 = 0x2a
(gdb) p/t variable # 二进制
$3 = 101010# 数组查看
(gdb) p *array@10 # 打印前10个元素
$4 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}# 结构体查看
(gdb) p *my_struct
$5 = {id = 1001, name = "Alice", data = {x=3.14, y=2.71}
}
2. 内存检查(x
命令)
x/[数量][格式][单位] 地址# 示例:以十六进制查看4个字节
(gdb) x/4xb 0x7fffffffd2a0
0x7fffffffd2a0: 0x2a 0x00 0x00 0x00# 格式说明:
# x - hex, d - decimal, s - string
# b - byte, h - halfword (2B), w - word (4B)
3. 修改变量值
(gdb) set variable counter = 0
(gdb) set *(int*)0x7fffffffd2a0 = 42 # 修改内存
四、程序执行控制
1. 单步执行对比
命令 | 行为 | 适用场景 |
---|---|---|
next | 执行一行,跳过函数 | 快速跨过库函数 |
step | 执行一行,进入函数 | 深入自定义函数 |
finish | 执行到当前函数返回 | 快速跳出当前函数 |
2. 高级流程控制
# 跳转执行(改变程序计数器)
(gdb) jump 45 # 跳转到45行# 强制函数返回
(gdb) return 0 # 立即返回并指定返回值# 信号处理
(gdb) handle SIGSEGV stop # 在段错误时暂停
五、堆栈分析(多函数调试)
调用栈分析实例
// demo.c
void func3() { /* 断点位置 */ }
void func2() { func3(); }
void func1() { func2(); }
int main() { func1(); }
(gdb) b func3
(gdb) run
(gdb) bt
#0 func3 () at demo.c:3
#1 0x400551 in func2 () at demo.c:2
#2 0x40055d in func1 () at demo.c:1
#3 0x400569 in main () at demo.c:4(gdb) frame 2 # 切换到func1的栈帧
(gdb) info locals # 查看func1的局部变量
六、多进程/线程调试
1. 多进程调试
# 跟踪子进程
(gdb) set follow-fork-mode child# 同时调试父子进程
(gdb) set detach-on-fork off
(gdb) info inferiors # 查看所有进程
(gdb) inferior 2 # 切换到进程2
2. 多线程调试
(gdb) info threadsId Target Id Frame
* 1 Thread 0x7f... (LWP 123) main () at demo.c:102 Thread 0x7f... (LWP 456) worker () at thread.c:5(gdb) thread 2 # 切换到线程2
(gdb) b thread.c:10 thread 2 # 线程专属断点
七、高级功能
1. 观察点(Watchpoints)
# 监控变量变化
(gdb) watch counter
Hardware watchpoint 1: counter# 监控表达式
(gdb) watch (counter > 100)# 读写监控
(gdb) rwatch variable # 读监控
(gdb) awatch variable # 读写监控
2. 反向调试(需安装rr)
rr record ./demo # 记录执行
rr replay # 回放调试
(gdb) reverse-step # 反向单步
3. 自定义命令
.gdbinit
配置文件示例:
# 打印STL容器内容
python
import sys
sys.path.insert(0, '/path/to/gdb/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers(None)
end# 自定义命令
define printallprint var1print var2print var3
end
八、实战调试示例
调试段错误(Segmentation Fault)
(gdb) run
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400536 in access_memory () at fault.c:8
8 *ptr = 100; // 非法写操作(gdb) bt
#0 0x400536 in access_memory () at fault.c:8
#1 0x400556 in main () at fault.c:15(gdb) frame 0
(gdb) p ptr
$1 = (int *) 0x0 # 空指针!
九、GDB 可视化增强
TUI 模式(文本界面)
gdb -tui ./demo # 启动TUI
常用TUI命令
快捷键 | 功能 |
---|---|
Ctrl + X A | 切换TUI/普通模式 |
Ctrl + L | 刷新屏幕 |
Win + 方向键 | 切换焦点窗口 |
十、性能分析辅助
1. 性能瓶颈定位
(gdb) b expensive_function
(gdb) commands
> silent # 静默执行
> backtrace # 每次命中打印调用栈
> continue
> end
2. 汇编级调试
(gdb) layout asm # 显示汇编窗口
(gdb) ni # 汇编级单步
(gdb) info registers # 查看寄存器
总结:GDB 调试流程
掌握GDB需要实践结合:
- 熟练使用
backtrace
分析调用栈 - 灵活运用条件断点和观察点
- 多进程/线程调试时注意上下文切换
- 结合core dump进行事后调试
- 通过
.gdbinit
定制个性化环境
附:官方文档链接 GDB Manual