C++ 我可以在 GDB 中的“内存访问”上设置断点吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/58851/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:32:43  来源:igfitidea点击:

Can I set a breakpoint on 'memory access' in GDB?

c++debugginggdbbreakpointsmemory-access

提问by TJ Seabrooks

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.

我正在通过 gdb 运行一个应用程序,我想在任何时候访问/更改特定变量时设置一个断点。有没有好的方法可以做到这一点?我也对在 C/C++ 中监视变量以查看它是否/何时更改的其他方法感兴趣。

回答by asksol

watchonly breaks on write, rwatchlet you break on read, and awatchlet you break on read/write.

watch只在写时中断,rwatch让你在读时中断,awatch让你在读/写时中断。

You can set read watchpoints on memory locations:

您可以在内存位置设置读取观察点:

gdb$ rwatch *0xfeedface
Hardware read watchpoint 2: *0xfeedface

but one limitation applies to the rwatch and awatch commands; you can't use gdb variables in expressions:

但是一个限制适用于 rwatch 和 awatch 命令;你不能在表达式中使用 gdb 变量:

gdb$ rwatch $ebx+0xec1a04f
Expression cannot be implemented with read/access watchpoint.

So you have to expand them yourself:

所以你必须自己扩展它们:

gdb$ print $ebx 
 = 0x135700
gdb$ rwatch *0x135700+0xec1a04f
Hardware read watchpoint 3: *0x135700 + 0xec1a04f
gdb$ c
Hardware read watchpoint 3: *0x135700 + 0xec1a04f

Value = 0xec34daf
0x9527d6e7 in objc_msgSend ()

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-watchpointsenvironment setting.

编辑:哦,顺便说一句。您需要硬件或软件支持。软件显然要慢得多。要了解您的操作系统是否支持硬件观察点,您可以查看can-use-hw-watchpoints环境设置。

gdb$ show can-use-hw-watchpoints
Debugger's willingness to use watchpoint hardware is 1.

回答by Paolo M

What you're looking for is called a watchpoint.

您要查找的内容称为watchpoint

Usage

用法

(gdb) watch foo: watch the value of variablefoo

(gdb) watch foo: 观察变量的值foo

(gdb) watch *(int*)0x12345678: watch the value pointed by an address, casted to whatever type you want

(gdb) watch *(int*)0x12345678: 观察地址指向的值,转换为你想要的任何类型

(gdb) watch a*b + c/d: watch an arbitrarily complex expression, valid in the program's native language

(gdb) watch a*b + c/d: 观看任意复杂的表达式,在程序的母语中有效

Watchpoints are of three kinds:

观察点分为三种:

  • watch: gdb will break when a writeoccurs
  • rwatch: gdb will break wnen a readoccurs
  • awatch: gdb will break in both cases
  • watch: gdb 会在发生时中断
  • rwatch: gdb 将在发生读取时中断
  • awatch:gdb 在这两种情况下都会中断

You may choose the more appropriate for your needs.

您可以选择更适合您的需求。

For more information, check thisout.

有关更多信息,请查看此内容

回答by Smirnov

Assuming the first answer is referring to the C-like syntax (char *)(0x135700 +0xec1a04f)then the answer to do rwatch *0x135700+0xec1a04fis incorrect. The correct syntax is rwatch *(0x135700+0xec1a04f).

假设第一个答案是指类似 C 的语法,(char *)(0x135700 +0xec1a04f)那么 do 的答案rwatch *0x135700+0xec1a04f是不正确的。正确的语法是rwatch *(0x135700+0xec1a04f).

The lack of ()s there caused me a great deal of pain trying to use watchpoints myself.

()那里缺少s 给我自己尝试使用观察点带来了很大的痛苦。

回答by mweerden

I just tried the following:

我只是尝试了以下方法:

 $ cat gdbtest.c
 int abc = 43;

 int main()
 {
   abc = 10;
 }
 $ gcc -g -o gdbtest gdbtest.c
 $ gdb gdbtest
 ...
 (gdb) watch abc
 Hardware watchpoint 1: abc
 (gdb) r
 Starting program: /home/mweerden/gdbtest 
 ...

 Old value = 43
 New value = 10
 main () at gdbtest.c:6
 6       }
 (gdb) quit

So it seems possible, but you do appear to need some hardware support.

所以这似乎是可能的,但您似乎确实需要一些硬件支持。

回答by higgs241

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:

使用 watch 查看何时写入变量,读取时使用 rwatch,读取/写入时使用 awatch,如上所述。但是,请注意,要使用此命令,您必须破坏程序,并且在破坏程序时变量必须在范围内:

Use the watch command. The argument to the watch command is an expression that is evaluated. This implies that the variabel you want to set a watchpoint on must be in the current scope. So, to set a watchpoint on a non-global variable, you must have set a breakpoint that will stop your program when the variable is in scope. You set the watchpoint after the program breaks.

使用监视命令。watch 命令的参数是一个被评估的表达式。这意味着您要设置观察点的变量必须在当前范围内。因此,要在非全局变量上设置观察点,您必须设置一个断点,当变量在范围内时,该断点将停止您的程序。在程序中断后设置观察点。