C++调试相关

2025/04/17 C++调试相关 共 1786 字,约 6 分钟

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 被访问或修改时中断

注意事项

  • 结合了 watchrwatch 的功能,但硬件支持更复杂。

通用规则与注意事项(来自官方文档)

  1. 硬件 vs 软件观察点

    • 硬件观察点依赖调试寄存器的支持,速度快;若无硬件支持,GDB 使用软件模拟(速度慢,且可能不准确)。
    • 使用 set can-use-hw-watchpoints 0 强制禁用硬件观察点。
  2. 作用域限制

    • 局部变量观察点在离开作用域后自动失效。
    • 全局变量或内存地址观察点持续有效。
  3. 表达式类型

    • 可以是简单变量、复杂表达式(如 array[5])、类型转换表达式(如 *(int*)0x1234)。
  4. 条件观察点

    • 可结合 condition 命令设置触发条件:

      (gdb) watch x if x > 100  # 仅当 x > 100 且被修改时中断
      
  5. 查看/删除观察点

    • info watchpoints 列出所有观察点。
    • delete <num> 删除编号为 num 的观察点。

参考

  • Debugging with gdb - Tenth Edition, for gdb version 16.2
  • C++代码调试的艺术

文档信息

Search

    Table of Contents