C++调试相关
GDB常用命令
GDB的手册有900多页,比较难快速定位到需要用的命令,本文意在记录一下比较有用但难以记忆的命令和使用场景。
0. 基础知识和命令使用
基础命令,例如单步,打断点,查看调用栈,查看变量等可以找个教程或者书籍参考。
1.查看进程内存空间映射
info proc mappings
或者直接检查特定的地址:
maintenance info sections
2.检查地址有效性
gdb 的x命令,也就是examine命令可以用来检查地址内存的合法性,通常用法如下:
n:是正整数,表示需要显示的内存单元的个数,即从当前地址向后显示n个内存单元的内容,
一个内存单元的大小由第三个参数u定义。
f:表示addr指向的内存内容的输出格式,s对应输出字符串,此处需特别注意输出整型数据的格式:
x 按十六进制格式显示变量.
d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。
u:就是指以多少个字节作为一个内存单元-unit,默认为4。u还可以用被一些字符表示:
如b=1 byte, h=2 bytes,w=4 bytes,g=8 bytes.
<addr>:表示内存地址。
例如x/8bx addr就是查看addr地址后的8个1字节(b)内存,并以16进制(x)格式输出。
- 正常情况:显示可读的数值(如引用计数值、对象指针)。
- 已释放内存:可能显示垃圾值或触发
Cannot access memory at address 0x6c6e62e8错误。
3.观察点使用
1. watch 命令
作用
当指定表达式(变量、内存地址等)的值被写入(修改)时触发中断。
语法
watch [-l|-location] <expr>
expr可以是变量名(如x)、内存地址(如*(int*)0x1234)或复杂表达式。-l选项强制观察expr指向的内存地址,而非表达式本身的值(适用于指针或引用)。
示例
(gdb) watch x # 变量 x 被修改时中断
(gdb) watch *(int*)0x404000 # 监控地址 0x404000 的整数值变化
(gdb) watch -l p->data # 监控 p->data 的地址,即使 p 指向的对象变化
注意事项
- 若变量是局部变量,离开作用域后观察点会自动删除。
- 需要硬件支持硬件观察点(否则 GDB 使用软件模拟,显著降低程序速度)。
2. rwatch 命令
作用
当指定表达式被读取时触发中断。
语法
rwatch [-l|-location] <expr>
- 语法与
watch相同,但触发条件是读取而非写入。
示例
(gdb) rwatch x # 变量 x 被读取时中断
(gdb) rwatch *0x404000 # 地址 0x404000 的内容被读取时中断
注意事项
- 硬件支持的读取观察点比写入观察点更少见,可能在某些架构上不可用。
- 若硬件不支持,GDB 会报错。
3. awatch 命令
作用
当指定表达式被读取或写入时均触发中断。
语法
awatch [-l|-location] <expr>
- 语法与
watch相同,触发条件是读取或写入。
示例
(gdb) awatch x # x 被读取或修改时中断
(gdb) awatch *0x404000 # 地址 0x404000 被访问或修改时中断
注意事项
- 结合了
watch和rwatch的功能,但硬件支持更复杂。
通用规则与注意事项(来自官方文档)
硬件 vs 软件观察点
- 硬件观察点依赖调试寄存器的支持,速度快;若无硬件支持,GDB 使用软件模拟(速度慢,且可能不准确)。
- 使用
set can-use-hw-watchpoints 0强制禁用硬件观察点。
作用域限制
- 局部变量观察点在离开作用域后自动失效。
- 全局变量或内存地址观察点持续有效。
表达式类型
- 可以是简单变量、复杂表达式(如
array[5])、类型转换表达式(如*(int*)0x1234)。
- 可以是简单变量、复杂表达式(如
条件观察点
可结合
condition命令设置触发条件:(gdb) watch x if x > 100 # 仅当 x > 100 且被修改时中断
查看/删除观察点
info watchpoints列出所有观察点。delete <num>删除编号为num的观察点。
参考
- Debugging with gdb - Tenth Edition, for gdb version 16.2
- C++代码调试的艺术
文档信息
- 本文作者:JianZheng
- 本文链接:https://zhengjian526.github.io/left-handed_knife//2025/04/17/C++-debug-and-gdb/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)