gdb:更改特定对象时中断

时间:2012-09-07 14:48:38

标签: c++ debugging gdb breakpoints

我有一个在c ++中定义的对象,在整个项目中使用了指向它的各种函数和文件。我遇到了正在更新的数据的问题,所以我想调试它以查看发生了什么。理想情况下,我希望每次访问对象时都会中断。但是,watch需要特定的内存地址。所以,例如,如果我有:

class data{
public:
    int a;
    int b;
};

然后gdb只会在a被更改时中断,因为指向数据的指针指向a,但在b被更改时则不会。

data类覆盖的整个内存范围发生变化时,有没有办法中断?

1 个答案:

答案 0 :(得分:4)

  

当数据类覆盖的整个内存范围发生变化时,有没有办法中断?

也许

GDB硬件观察点在硬件中使用特殊的调试寄存器,并且这些寄存器的工作方式通常存在限制。在x86,您最多可以设置4个字大小的硬件观察点,例如,您可以在&data->a&data->b上为可以设置观察点,以及这将“覆盖”data的整个记忆。

我猜你的实际data有更多会员,所以4个字大小的观察点是不够的。

如果您在具有Valgrind支持的平台上,并且您的程序可以在Valgrind下执行,那么您可以使用Valgrind的内置gdbserver任意内存区域设置观察点

更新

  

我查看了您链接的页面,找不到我要找的内容

我不确定你在寻找什么。以下是展示其工作原理的示例会话:

#include <stdlib.h>

void foo(char *p)
{
  *p = 'a';
}

typedef struct {
  char buf[1024];
} data;

int main()
{
  data *d = calloc(1, sizeof(data));
  foo(d->buf + 999);
}

gcc -g main.c

valgrind --vgdb-error=0 ./a.out
...
==10345== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==10345==   /path/to/gdb ./a.out
==10345== and then give GDB the following command
==10345==   target remote | vgdb --pid=10345

... Valgrind现在等待调试器附加。

在另一个窗口中:

gdb ./a.out
GNU gdb (GDB) 7.4
...
(gdb) target remote | vgdb --pid=10345
relaying data between gdb and process 10345
[Switching to Thread 10345]
0x0000000004000af0 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) b main
Breakpoint 1 at 0x40053d: file main.c, line 14.
(gdb) c

Breakpoint 1, main () at main.c:14
14        data *d = calloc(1, sizeof(data));
(gdb) n
15        foo(d->buf + 999);
(gdb) watch *d
Hardware watchpoint 2: *d

请注意,已在整个 *d上设置了“硬件”观察点。 只有在Valgrind是硬件的意义上,它才是硬件观察点。

(gdb) p d.buf[999]
$1 = 0 '\000'
(gdb) c
Hardware watchpoint 2: *d

Old value = {buf = '\000' <repeats 1023 times>}
New value = {buf = '\000' <repeats 999 times>, "a", '\000' <repeats 23 times>}
foo (p=0x51b6457 "a") at main.c:6
6       }
(gdb) q

Voila:调试器在第999个元素被修改时停止,证明观察点“覆盖”了整个结构。