gpt4 book ai didi

gdb - 如何监视结构体成员中具有该类型的每个结构体变量?

转载 作者:行者123 更新时间:2023-12-01 16:11:50 25 4
gpt4 key购买 nike

我的结构成员被损坏,其中结构用于构建大树。我试图设置一个观察点,但“变量”已经各种名称(我见过的所有示例都使用显式全局变量,所以不要显示我正在寻找的示例)。

(gdb) watch *(OP*)->op.siblingA syntax error in expression, near `->op.sibling'.(gdb) watch *(struct op*)->op.siblingA syntax error in expression, near `->op.sibling'.(gdb) watch (struct op*)->op.siblingA syntax error in expression, near `->op.sibling'.

我最接近可接受的语法不起作用

(gdb) watch (struct op*)o->op.siblingNo symbol "o" in current context.

我缺少一种独立的表达形式吗变量名,并注意它是一个特定的事实什么样的结构?

这能够检测到结构体的 memset 覆盖吗?(即使没有,它也会帮助我排除一些原因)

是否有超出基本用法的 gdb 引用?(对于“基本”的一些定义)

最佳答案

正如 ninjalj 所说,你必须有一个地址才能观看;这就是观察点的全部要点。考虑以下示例:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct node {
long value;
struct node *next;
} node;

node *build_node(int x, node *next)
{
node *n = malloc(sizeof(*n));
n->value = x;
n->next = next;
return n;
}

int main()
{
node *n = build_node(1, NULL);
n = build_node(2, n);
n = build_node(3, n);

memset(&n->next->value, 0xFF, sizeof(long) + 3); // corrupt the list

return 0;
}

这里我生成一个整数列表,然后破坏它。让我们看看这在 GDB 中是什么样子的:

gdb -q ./a.out
Reading symbols for shared libraries .. done
(gdb) b main
Breakpoint 1 at 0x100000e0c: file foo.c, line 20.
(gdb) r
Starting program: /tmp/a.out
Reading symbols for shared libraries +. done

Breakpoint 1, main () at foo.c:20
20 node *n = build_node(1, NULL);

(gdb) b 26
Breakpoint 2 at 0x100000e8d: file foo.c, line 26.
(gdb) c
Continuing.

Breakpoint 2, main () at foo.c:26
26 return 0;
(gdb) p *n
$1 = {
value = 3,
next = 0x100100090
}
(gdb) p *n.next
$2 = {
value = -1,
next = 0x100ffffff
}

在这里,我们清楚地看到 n->next 已彻底损坏。假设我们不知道这发生在哪里,并且想通过 GDB 观察点找出答案。

首先,我们需要确定已损坏的地址:

(gdb) print &n.next.value
$3 = (long int *) 0x100100090
(gdb) watch *$3
Hardware watchpoint 3: *$3

这里我只是在地址 0x100100090 上设置了 8 个字节的观察点。

(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /private/tmp/a.out
warning: Could not set watchpoint 3
warning: Could not set watchpoint 3

Breakpoint 1, main () at foo.c:20
20 node *n = build_node(1, NULL);

我使用的是相当旧的 GDB 版本,它不知道如何在程序重新启动时正确禁用和重新启用硬件观察点。如果您使用更新的版本,您可能不会看到上述警告。当我停在断点 1 处时,我可以简单地重新启用观察点:

(gdb) enable 3
(gdb) c
Continuing.
Hardware watchpoint 3: *$3

Old value = 0
New value = 2
build_node (x=2, next=0x100100080) at foo.c:14
14 n->next = next;

好的,我们已经达到了预期点和预期值。下一次修改将破坏它,我们想知道这是在哪里发生的。

(gdb) c
Continuing.
Hardware watchpoint 3: *$3

Old value = 2
New value = 255
0x00007fff82fae450 in memset ()
(gdb) bt
#0 0x00007fff82fae450 in memset ()
#1 0x0000000100000ebe in __inline_memset_chk (__dest=0x100100090, __val=255, __len=11) at _string.h:80
#2 0x0000000100000e8d in main () at foo.c:24

瞧,您现在知道意外修改来自何处。

关于gdb - 如何监视结构体成员中具有该类型的每个结构体变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5557590/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com