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


244

我正在通过gdb运行应用程序,并且想在每次访问/更改特定变量时都设置断点。有一个好的方法吗?我还对其他监视C / C ++中的变量以查看是否/何时更改的方式感兴趣。

Answers:


286

观看仅在写入时中断,rwatch让您在读取时中断,而awatch让您在读取/写入时中断。

您可以在内存位置上设置读取监视点:

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

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

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

因此,您必须自己扩展它们:

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 ()

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

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

7
如果您想观看C ++方法的成员,我发现此变体非常有用:watch -location mTextFormatted
伊凡·武西卡(IvanVučica)2011年

如果我没有变量的地址怎么办?我可以使用它的名字吗?
拉菲·哈查杜安

5
您可以让GDB使用address-of运算符打印变量的地址。print &variable
2011年

1
这个答案没有说明命令正在监视的内存位置的大小watch。同时,这是阅读以上内容后浮现在脑海中的第一个问题。rwatch *0xfeedface实际上要看多少个字节?
AnT

8
@AnT,我假设它会监视单个字节,似乎是这样,但是您可以将其强制转换为特定类型,例如rwatch *(int *)0xfeedface,它将监视sizeof(int)字节:sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints。 html
asksol 2015年

28

您正在寻找的东西称为观察点

用法

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

(gdb) watch *(int*)0x12345678:观看地址指向的值,并将其转换为所需的任何类型

(gdb) watch a*b + c/d:观看任意复杂的表达式,以该程序的本地语言有效

监视点有以下三种:

  • 注意:发生写操作时gdb会中断
  • rwatch:GDB将打破wnen一
  • awatch两种情况下 gdb都会中断

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

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


5
我写了另一个答案,因为现有的答案对我来说似乎并不那么简单……
Paolo M

25

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

()那里缺少s导致我自己尝试使用观察点时非常痛苦。


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

因此似乎有可能,但是您似乎确实需要一些硬件支持。


如果您的平台不支持硬件监视点,则gdb应该回退到软件监视点。
Tod

2

如上所述,使用watch可以查看何时将变量写入变量,使用rwatch可以读取变量,以及从/ to写入变量时可以监视awatch。但是,请注意,要使用此命令,必须中断程序,并且在中断程序时变量必须在范围内:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.