我可以在“内存访问”上设置断点吗? 在GDB?
我正在通过 gdb 运行应用程序,并且我想在访问/更改特定变量的任何时间设置断点。 有没有好的方法来做到这一点? 我也对监视 C/C++ 中的变量以查看它是否/何时发生变化的其他方法感兴趣。
I am running an application through gdb and I want to set a breakpoint for any time a specific variable is accessed / changed. Is there a good method for doing this? I would also be interested in other ways to monitor a variable in C/C++ to see if/when it changes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
watch 仅在写入时中断,rwatch 让您在读取时中断,awatch 让您在读/写时中断。
您可以在内存位置设置读取观察点:
但 rwatch 和 awatch 命令存在一个限制; 你不能使用 gdb 变量
在表达式中:
所以你必须自己扩展它们:
编辑:哦,顺便说一句。 您需要硬件或软件支持。 软件显然要慢得多。 要了解您的操作系统是否支持硬件观察点,您可以查看 can-use-hw-watchpoints 环境设置。
watch only breaks on write, rwatch let you break on read, and awatch let you break on read/write.
You can set read watchpoints on memory locations:
but one limitation applies to the rwatch and awatch commands; you can't use gdb variables
in expressions:
So you have to expand them yourself:
Edit: Oh, and by the way. You need either hardware or software support. Software is obviously much slower. To find out if your OS supports hardware watchpoints you can see the can-use-hw-watchpoints environment setting.
您正在寻找的内容称为观察点。
用法
(gdb) watch foo
:观察变量foo
(gdb) watch *( int*)0x12345678
:监视地址指向的值,转换为您想要的任何类型(gdb) watch a*b + c/d
:watch任意复杂表达式,在程序的本地语言中有效观察点分为三种:
您可以选择更适合您的情况需要。
有关更多信息,请查看此。
What you're looking for is called a watchpoint.
Usage
(gdb) watch foo
: watch the value of variablefoo
(gdb) watch *(int*)0x12345678
: watch the value pointed by an address, casted to whatever type you want(gdb) watch a*b + c/d
: watch an arbitrarily complex expression, valid in the program's native languageWatchpoints are of three kinds:
You may choose the more appropriate for your needs.
For more information, check this out.
我刚刚尝试了以下操作:
所以这似乎是可能的,但您似乎确实需要一些硬件支持。
I just tried the following:
So it seems possible, but you do appear to need some hardware support.
假设第一个答案是指类似 C 的语法
(char *)(0x135700 +0xec1a04f)
,那么 dorwatch *0x135700+0xec1a04f
的答案是不正确的。 正确的语法是rwatch *(0x135700+0xec1a04f)
。那里缺少
()
给我自己尝试使用观察点带来了很大的痛苦。Assuming the first answer is referring to the C-like syntax
(char *)(0x135700 +0xec1a04f)
then the answer to dorwatch *0x135700+0xec1a04f
is incorrect. The correct syntax isrwatch *(0x135700+0xec1a04f)
.The lack of
()
s there caused me a great deal of pain trying to use watchpoints myself.使用 watch 来查看变量何时被写入,rwatch 何时被读取,awatch 何时被读取/写入,如上所述。 但是,请注意,要使用此命令,您必须中断程序,并且当您中断程序时变量必须在范围内:
Use watch to see when a variable is written to, rwatch when it is read and awatch when it is read/written from/to, as noted above. However, please note that to use this command, you must break the program, and the variable must be in scope when you've broken the program:
除了 asksol 和 Paolo M
我一开始没明白,为什么我们需要投射结果。 虽然我读到了这个: https://sourceware.org/gdb/onlinedocs/gdb /Set-Watchpoints.html,但这对我来说并不直观。
所以我做了一个实验以使结果更清晰:
代码:(假设 int main() 位于第 3 行;int i=0 位于第 5 行,其他代码来自第 10 行)
然后我使用可执行文件启动 gdb
在我的第一次尝试中,我在变量的位置设置了断点而不进行强制转换,以下是显示的结果
,我们可以看到我设置的第 10 行断点被击中。 gdb 没有中断,因为虽然变量我经历了更改,但正在监视的位置
在我的第二次尝试中没有更改(由于字节顺序,因为它继续保持全 0),我对要监视的变量的地址进行了转换对于所有 sizeof(int) 字节。 这次:
gdb 中断,因为它检测到值已更改。
In addition to what has already been answered/commented by asksol and Paolo M
I didn't at first read understand, why do we need to cast the results. Though I read this: https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html, yet it wasn't intuitive to me..
So I did an experiment to make the result clearer:
Code: (Let's say that int main() is at Line 3; int i=0 is at Line 5 and other code.. is from Line 10)
then i started gdb with the executable file
in my first attempt, i set the breakpoint on the location of variable without casting, following were the results displayed
as we could see breakpoint was hit for line 10 which was set by me. gdb didn't break because although variable i underwent change yet the location being watched didn't change (due to endianness, since it continued to remain all 0's)
in my second attempt, i did the casting on the address of the variable to watch for all the sizeof(int) bytes. this time:
gdb break since it detected the value has changed.