我正在通过gdb运行一个应用程序,并希望为特定变量被访问/更改的任何时候设置断点。有没有好方法可以做到这一点? 我还对其他监视C / C ++变量的方法感兴趣,以查看它何时发生更改。
我正在通过gdb运行一个应用程序,并希望为特定变量被访问/更改的任何时候设置断点。有没有好方法可以做到这一点? 我还对其他监视C / C ++变量的方法感兴趣,以查看它何时发生更改。
您可以在内存位置上设置读取观察点:
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.
(char *)(0x135700 +0xec1a04f)
,那么执行 rwatch *0x135700+0xec1a04f
是错误的。正确的语法应该是 rwatch *(0x135700+0xec1a04f)
。我刚刚尝试了以下内容:
$ 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
看起来是有可能的,但你似乎需要一些硬件支持。
一开始我并不理解为什么我们需要转换结果。虽然我读了https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html,但对我来说这还不直观。
因此,我进行了一个实验,以使结果更清晰:
代码:(假设int main()在第3行;int i=0在第5行;其他代码从第10行开始)int main()
{
int i = 0;
int j;
i = 3840 // binary 1100 0000 0000 to take into account endianness
other code..
}
然后我用可执行文件启动了gdb
在我的第一次尝试中,我设置了变量位置的断点而没有进行类型转换,结果如下所示
Thread 1 "testing2" h
Breakpoint 2 at 0x10040109b: file testing2.c, line 10.
(gdb) s
7 i = 3840;
(gdb) p i
$1 = 0
(gdb) p &i
$2 = (int *) 0xffffcbfc
(gdb) watch *0xffffcbfc
Hardware watchpoint 3: *0xffffcbfc
(gdb) s
[New Thread 13168.0xa74]
Thread 1 "testing2" hit Breakpoint 2, main () at testing2.c:10
10 b = a;
(gdb) p i
$3 = 3840
(gdb) p *0xffffcbfc
$4 = 3840
(gdb) p/t *0xffffcbfc
$5 = 111100000000
正如我们所看到的,断点命中了我设置的第10行。GDB没有中断,因为尽管变量i发生了变化,但由于字节序问题,被监视的位置没有改变(因为它仍然保持全0)。
在我的第二次尝试中,我对要监视的变量地址进行了所有sizeof(int)字节的强制转换。这一次:
(gdb) p &i
$6 = (int *) 0xffffcbfc
(gdb) p i
$7 = 0
(gdb) watch *(int *) 0xffffcbfc
Hardware watchpoint 6: *(int *) 0xffffcbfc
(gdb) b 10
Breakpoint 7 at 0x10040109b: file testing2.c, line 10.
(gdb) i b
Num Type Disp Enb Address What
6 hw watchpoint keep y *(int *) 0xffffcbfc
7 breakpoint keep y 0x000000010040109b in main at testing2.c:10
(gdb) n
[New Thread 21508.0x3c30]
Thread 1 "testing2" hit Hardware watchpoint 6: *(int *) 0xffffcbfc
Old value = 0
New value = 3840
Thread 1 "testing2" hit Breakpoint 7, main () at testing2.c:10
10 b = a;
由于检测到值已更改,gdb断点。
watch -location mTextFormatted
。 - Ivan Vučicaprint &variable
。 - Loduwijkwatch
命令所监视的内存位置的大小。读完上面的内容后,第一个浮现在脑海中的问题是:rwatch *0xfeedface
会实际监视多少字节?请注意,不要改变原意。 - AnT stands with Russiarwatch *(int *)0xfeedface
,它将监视sizeof(int)
个字节:https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html - asksol