我可以在GDB中的'内存访问'上设置断点吗?

TJ *_*oks 236 debugging gdb breakpoints

我正在通过gdb运行应用程序,我想在访问/更改特定变量的任何时候设置断点.有这么好的方法吗?我也有兴趣用其他方法监视C/C++中的变量,看看它是否/何时发生变化.

ask*_*sol 277

手表上只写符,rwatch让你读破发,并awatch让你打破的读/写.

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

gdb$ rwatch *0xfeedface
Hardware read watchpoint 2: *0xfeedface
Run Code Online (Sandbox Code Playgroud)

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

gdb$ rwatch $ebx+0xec1a04f
Expression cannot be implemented with read/access watchpoint.
Run Code Online (Sandbox Code Playgroud)

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

gdb$ print $ebx 
$13 = 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 ()
Run Code Online (Sandbox Code Playgroud)

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

gdb$ show can-use-hw-watchpoints
Debugger's willingness to use watchpoint hardware is 1.
Run Code Online (Sandbox Code Playgroud)

  • @AnT,我假设它会观察单个字节,这似乎是这种情况,但你可以将它转换为特定类型,例如`rwatch*(int*)0xfeedface`,它将观察`sizeof(int)`bytes :https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html (6认同)
  • 如果你想看一个C++方法的成员,我发现这个变种非常有用:`watch -location mTextFormatted`. (5认同)
  • 您可以让GDB使用address-of运算符打印变量的地址.`print&variable` (5认同)
  • 这个答案没有说明`watch`命令正在监视的内存位置的*大小*。同时,这是阅读上述内容后首先想到的问题。`rwatch *0xfeedface` 将实际观看多少字节? (2认同)

Pao*_*o M 25

您正在寻找的是一个观察点.

用法

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

(gdb) watch *(int*)0x12345678:观察地址指向的值,按照您想要的任何类型

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

观察点有三种:

  • watch:写入时gdb会中断
  • rwatch:gdb会破坏读取的发生
  • awatch:gdb在两种情况下都会中断

您可以选择更适合您需求的产品.

有关更多信息,请查看信息.

  • 我写了**另一个**答案,因为现有的答案对我来说似乎不太直白...... (4认同)

小智 23

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

()那里缺乏s导致我试图自己使用观察点的痛苦.


mwe*_*den 9

我只是尝试了以下内容:

 $ 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
Run Code Online (Sandbox Code Playgroud)

所以看起来可能,但你确实需要一些硬件支持.