在gdb中观察内存范围?

ibl*_*lue 27 c linux debugging 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.
Run Code Online (Sandbox Code Playgroud)

已经有人问过这个问题,答案是,有可能用valgrind做到这一点.不幸的是,答案中没有任何示例或对valgrind手册的引用,所以它不是很有启发性:如何使用gdb来监视整个内存区域的任何变化?

那么:我怎样才能观看整个内存区域?

小智 26

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

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

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

  • 在我花了很多时间摆弄`mprotect`并滥用SIGSEV处理程序打破内存访问后,我尝试了这个.它完美地运作.你救了我的一天.谢谢! (3认同)

Cra*_*rks 12

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

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


pre*_*uin 2

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

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

使用命令:

watch *(char [100]*)&gbuf
Run Code Online (Sandbox Code Playgroud)

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