Gdb 如何监视具有该类型的每个结构变量的结构成员?

Gdb 如何监视具有该类型的每个结构变量的结构成员?,gdb,Gdb,我得到了一个struct成员的损坏,其中struct用于构建 大树。我正试图设置一个观察点,但“变量”已 各种名称(我看到的所有示例都使用显式全局变量, 因此,不要展示我正在寻找的例子) (gdb)监视*(OP*)->OP.sibling 表达式中靠近“->op.sibling”的语法错误。 (gdb)监视*(结构操作*)->操作同级 表达式中靠近“->op.sibling”的语法错误。 (gdb)监视(结构操作*)->操作同级 表达式中靠近“->op.sibling”的语法错误。 最接近可接受

我得到了一个struct成员的损坏,其中struct用于构建 大树。我正试图设置一个观察点,但“变量”已 各种名称(我看到的所有示例都使用显式全局变量, 因此,不要展示我正在寻找的例子)

(gdb)监视*(OP*)->OP.sibling 表达式中靠近“->op.sibling”的语法错误。 (gdb)监视*(结构操作*)->操作同级 表达式中靠近“->op.sibling”的语法错误。 (gdb)监视(结构操作*)->操作同级 表达式中靠近“->op.sibling”的语法错误。 最接近可接受的语法不起作用

(gdb) watch (struct op*)o->op.sibling No symbol "o" in current context. (gdb)监视(struct op*)o->op.sibling 当前上下文中没有符号“o”。 是否有一种我缺少的独立表达形式 变量名,并注意它是一个特定的 什么样的结构

这是否能够检测结构的memset覆盖? (即使没有,也可以帮助我排除一些原因)

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

,您希望它如何工作?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;
}
在这里,我们清楚地看到,
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) 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