ewo*_*wok 3 c++ debugging gdb breakpoints
我有一个用 C++ 定义的对象,并在整个项目的各种函数和文件中使用了指向它的指针。我在更新数据时遇到问题,因此我想对其进行调试以查看发生了什么。理想情况下,我希望每次访问对象时都中断。但是,watch需要特定的内存地址。因此,举例来说,如果我有:
class data{
public:
int a;
int b;
};
Run Code Online (Sandbox Code Playgroud)
那么gdb只会在a被改变时中断,因为指向数据的指针指向a,但在b被改变时不会中断。
data每当类覆盖的整个内存范围发生更改时,是否有办法中断?
每当数据类覆盖的整个内存范围发生更改时,是否有办法中断?
也许。
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
Run Code Online (Sandbox Code Playgroud)
... 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
Run Code Online (Sandbox Code Playgroud)
请注意,已在整个 *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
Run Code Online (Sandbox Code Playgroud)
瞧:当第 999 个元素被修改时,调试器停止,证明观察点“覆盖”了整个结构。