我的程序在运行几个小时后因为分段错误而随机崩溃。我的环境是Ubuntu(Linux)
当我尝试打印崩溃时正在访问的数据结构时,指针总是指向无效的内存。
(gdb) p *xxx_info[8]
**Cannot access memory at address 0x7fd200000000**
(gdb)
为了检测数据损坏,我添加了两个使用明确定义的值进行硬编码的fence变量,以便我可以检测到内存损坏。我看到导致我的进程崩溃的链表节点的fence变量已经从我之前的日志中被违反了。
(gdb) p xxx_info
$2 = {0x7fd248000c30, 0x7fd248001050, 0x7fd248000b30, 0x7fd248000d40, 0x7fd248000f50, 0x0,
0x7fd248001160, 0x7fd248001280, 0x7fd200000000, 0x7fd2480008c0,
0x7fd248003000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
(gdb) p xxx_info[8]
$3 = (xxx_info_t *) 0x7fd200000000
(gdb) p *xxx_info[8]
**Cannot access memory at address 0x7fd200000000**
(gdb)
我在数据结构的开头和结尾添加了两个fence变量。
(gdb) pt xxx_info_t
type = struct xxx_info_t {
uint32_t begin_fence;
char *str;
int cluster_id;
uint32_t end_fence;
}
在正常情况下,fence变量必须始终为0xdeaddead,如下所示:
(gdb) p/x *xxx_info[7]
$4 = {**begin_fence= 0xdeaddead**, str= 0x7fd248002f10, cluster_id= 0x1f2, **end_fence= 0xdeaddead**}
(gdb)
每当我访问指针数组xxx_info时,我都会检查每个索引的fence值。我注意到我会收到错误消息,指出索引8的fence变量看起来已损坏。稍后,代码在访问索引8时崩溃。
这意味着在某处我覆盖了数组xxx_info的索引8所指向的内存地址。
我的问题是:
如何调试这些错误?我可以动态设置一些断点,以便每当有人覆盖我抱怨和断言的内存地址时。如果这是一个有人腐败的全局变量,我可以设置一个HW断点。由于这是在堆(i malloc)上创建的列表,因此我将获得的地址将是动态的,因此我无法使用内存断点/观察点。
关于我能做什么的任何想法?