Linux 在 gdb 中观察内存范围?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11004374/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Watch a memory range in gdb?
提问by iblue
I am debugging a program in gdb and I want the program to stop when the memory region 0x08049000 to 0x0804a000 is accessed. When I try to set memory breakpoints manually, gdb does not seem to support more than two locations at a time.
我正在 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.
There is already a question where this has been asked and the answer was, that it may be possible to do this with valgrind. Unfortunately the answer does not contain any examples or reference to the valgrind manual, so it was not very enlightning: How can gdb be used to watch for any changes in an entire region of memory?
已经有人问过这个问题,答案是,可以用 valgrind 来做到这一点。不幸的是,答案不包含任何示例或对 valgrind 手册的引用,因此它不是很有启发性:如何使用 gdb 来观察整个内存区域的任何变化?
So: How can I watch the whole memory region?
那么:如何查看整个内存区域?
采纳答案by phd
If you use GDB 7.4 together with Valgrind 3.7.0, then you have unlimited "emulated" hardware watchpoints.
如果您将 GDB 7.4 与 Valgrind 3.7.0 一起使用,那么您将拥有无限的“模拟”硬件观察点。
Start your program under Valgrind, giving the arguments
--vgdb=full --vgdb-error=0
then use GDB to connect to it (target remote | vgdb
).
Then you can e.g. watch
or awatch
or rwatch
a memory range by doing
rwatch (char[100]) *0x5180040
在 Valgrind 下启动您的程序,提供参数
--vgdb=full --vgdb-error=0
然后使用 GDB 连接到它 ( target remote | vgdb
)。然后你就可以,例如watch
或awatch
或rwatch
做一个内存范围
rwatch (char[100]) *0x5180040
See the Valgrind user manual on gdb integrationfor more details
有关更多详细信息,请参阅有关 gdb 集成的 Valgrind 用户手册
回答by Crashworks
The feature that detects when a memory address has changed is called a hardware breakpoint, and it's actually a feature of the CPU — a register inside the memory controller that detects when a specific address is accessed, and triggers a debugger break interrupt. Unfortunately the x86 architectureonly has four such registersand that's why you're limited in the number of memory watch breakpoints you can set.
检测内存地址何时发生变化的功能称为硬件断点,它实际上是 CPU 的一个功能——内存控制器内部的一个寄存器,用于检测特定地址何时被访问,并触发调试器中断中断。不幸的是,x86 架构只有四个这样的寄存器,这就是您可以设置的内存观察断点数量有限的原因。
That's why you need to use something like valgrind; if you want to watch an entire region, you have to do it by using software that simulates the memory access patterns. I don't know if valgrind actually supports watching entire memory ranges, though. You may have to patch it yourself. Modify VALGRIND_MAKE_MEM_NOACCESS() to throw a breakpoint but then allow the program to continue, maybe.
这就是为什么你需要使用 valgrind 之类的东西;如果你想观察整个区域,你必须使用模拟内存访问模式的软件来完成。不过,我不知道 valgrind 是否真的支持查看整个内存范围。您可能需要自己修补它。修改 VALGRIND_MAKE_MEM_NOACCESS() 以抛出断点,然后允许程序继续,也许吧。