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

时间:2020-03-05 18:52:10  来源:igfitidea点击:

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

解决方案

回答

我只是尝试了以下方法:

$ 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

这样看来有可能,但我们似乎确实需要一些硬件支持。

回答

watch仅在写入时中断,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 
 = 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.

回答

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

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