33

我正在 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 做到这一点。不幸的是,答案不包含任何示例或对 valgrind 手册的参考,所以它不是很启发性:如何使用 gdb 来监视整个内存区域的任何变化?

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

4

2 回答 2

30

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

在 Valgrind 下启动您的程序,提供参数, --vgdb=full --vgdb-error=0 然后使用 GDB 连接到它(target remote | vgdb)。然后你可以通过做例如watchawatchrwatch内存范围 rwatch (char[100]) *0x5180040

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

于 2012-06-13T20:00:15.600 回答
13

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

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

于 2012-06-12T20:48:13.210 回答