C语言 以 gdb 为单位监视内存范围



我正在 gdb 中调试一个程序,我希望该程序在访问0x08049000 0x0804a000的内存区域时停止。当我尝试手动设置内存断点时,gdb 似乎一次不支持两个以上的位置。

(gdb) awatch *0x08049000
Hardware access (read/write) watchpoint 1: *0x08049000
(gdb) awatch *0x08049001
Hardware access (read/write) watchpoint 2: *0x08049001
(gdb) awatch *0x08049002
Hardware access (read/write) watchpoint 3: *0x08049002
(gdb) run
Starting program: /home/iblue/git/some-code/some-executable
Warning:
Could not insert hardware watchpoint 3.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.

已经有一个问题被问到,答案是,也许可以用瓦尔格林德做到这一点。不幸的是,答案不包含任何示例或对valgrind手册的引用,因此它不是很有启发性:如何使用gdb来监视整个内存区域的任何变化?

那么:如何观看整个内存区域?

如果您将 GDB 7.4 与 Valgrind 3.7.0 一起使用,那么您有无限的"模拟"硬件观察点。

在瓦尔格林德下启动你的程序,给出参数 --vgdb=full --vgdb-error=0然后使用 GDB 连接到它 ( target remote | vgdb )。然后你可以例如 watchawatchrwatch内存范围,方法是 rwatch (char[100]) *0x5180040

有关更多详细信息,请参阅 Valgrind 用户手册 gdb 集成

检测内存地址何时更改的功能称为硬件断点,它实际上是 CPU 的一个功能——内存控制器内的寄存器,用于检测何时访问特定地址,并触发调试器中断中断。 不幸的是,x86 体系结构只有四个这样的寄存器,这就是为什么您可以设置的内存监视断点数量有限的原因。

这就是为什么你需要使用像valgrind这样的东西;如果你想观察整个区域,你必须使用模拟内存访问模式的软件来完成。不过,我不知道 valgrind 是否真的支持观看整个内存范围。您可能需要自己修补它。修改 VALGRIND_MAKE_MEM_NOACCESS() 以抛出断点,但随后允许程序继续,也许。

我已经

验证了最近的 gdb 本身现在确实支持监视一系列地址,那么 Valgrind 不是必须的,正如其他答案所建议的那样,测试 env:

  • GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
  • 第 11 代智能英特尔® 酷睿™ i7-11800H @ 2.30GHz

使用命令:

watch *(char [100]*)&gbuf

然后我们开始观察地址范围[gbuf, gbuf + 100)

最新更新