我的结构变量指针存在问题。我刚开始使用GDB调试问题。由于分段错误,应用程序在下面的代码行上命中时停止。 ptr_var是指向结构的指针
ptr_var->page = 0;
我发现在一系列函数调用之后ptr_var被设置为无效内存0x0,这在分配值" 0"时会导致分段错误。结构成员"页面"。函数调用系列没有对ptr_var的引用。以前分配给ptr_var的旧地址仍在内存中。我仍然可以使用旧地址从struct ptr_var打印成员的值。下面的GDB会话显示我正在使用其地址
打印struct ptr_var的字符串成员(gdb) x /s *0x7e11c0
0x7e0810: "Sample String"
我无法判断变量ptr_var何时被分配了无效地址0x0。我是GDB的新手,也是普通的C程序员。非常感谢您对此事的帮助。谢谢。
答案 0 :(得分:2)
您要做的是设置观察点,每次修改结构的成员时,GDB都会停止执行。
使用以下示例代码
typedef struct {
int val;
} Foo;
int main(void) {
Foo foo;
foo.val = 5;
foo.val = 10;
}
在创建结构时删除断点并执行watch -l foo.val
然后每次更改该成员时,您将获得休息。以下是我的GDB会话,我的输入
(gdb) break test.c:8
Breakpoint 3 at 0x4006f9: file test.c, line 8.
(gdb) run
Starting program: /usr/home/sean/a.out
Breakpoint 3, main () at test.c:9
9 foo.val = 5;
(gdb) watch -l foo.val
Hardware watchpoint 4: -location foo.val
(gdb) cont
Continuing.
Hardware watchpoint 4: -location foo.val
Old value = 0
New value = 5
main () at test.c:10
(gdb) cont
Continuing.
Hardware watchpoint 4: -location foo.val
Old value = 5
New value = 10
main () at test.c:11
(gdb) cont
答案 1 :(得分:1)
如果您可以重新运行,那么在ptr_var
正确的位置休息,您可以在ptr_var
上设置一个观察点,如下所示:(gdb) watch ptr_var
。现在当你每次ptr_var
被修改时你继续gdb应该停止。
这是一个例子。这确实包含未定义的行为,因为我试图重现一个错误,但希望它应该足以告诉你我所建议的内容:
#include <stdio.h>
#include <stdint.h>
int target1;
int target2;
void
bad_func (int **bar)
{
/* Set contents of bar. */
uintptr_t ptr = (uintptr_t) bar;
printf ("Should clear %p\n", (void *) ptr);
ptr += sizeof (int *);
printf ("Will clear %p\n", (void *) ptr);
/* Bad! We just corrupted foo (maybe). */
*((int **) ptr) = NULL;
}
int
main ()
{
int *foo = &target1;
int *bar = &target2;
printf ("&foo = %p\n", (void *) &foo);
printf ("&boo = %p\n", (void *) &bar);
bad_func (&bar);
return *foo;
}
这是一个gdb会话:
(gdb) break bad_func
Breakpoint 1 at 0x400542: file watch.c, line 11.
(gdb) r
&foo = 0x7fffffffdb88
&boo = 0x7fffffffdb80
Breakpoint 1, bad_func (bar=0x7fffffffdb80) at watch.c:11
11 uintptr_t ptr = (uintptr_t) bar;
(gdb) up
#1 0x00000000004005d9 in main () at watch.c:27
27 bad_func (&bar);
(gdb) watch foo
Hardware watchpoint 2: foo
(gdb) c
Continuing.
Should clear 0x7fffffffdb80
Will clear 0x7fffffffdb88
Hardware watchpoint 2: foo
Old value = (int *) 0x60103c <target1>
New value = (int *) 0x0
bad_func (bar=0x7fffffffdb80) at watch.c:18
18 }
(gdb)
由于某些原因,观察点似乎在更改后触发了行,即使我使用-O0编译它,这有点遗憾。尽管如此,它通常足够接近以帮助确定问题。
答案 2 :(得分:0)
对于这类问题,我经常使用旧的电围栏库,它可以用来查找“超出malloc()内存分配边界的软件”中的错误。您将在此页面找到所有说明和基本用法: http://elinux.org/Electric_Fence
(在上面链接的页面的最后,您将找到下载链接)