如何检测C程序内存损坏来源?free()崩溃原因排查求助
问题背景
程序崩溃生成core文件,分析后发现崩溃发生在调用free()时,传入的地址无效:
#1 0x000055ea2d52f630 in __free [__be___free] (ptr=0x7f8bd51a63ef, saved_caller_pc=0x55ea29cceb76 <abc+998>, attr=0x0)
目标地址0x7f8bd51a63ef无效:x86_64架构下指针是8字节对齐的,合法地址应以0或8结尾,但该地址以f结尾。通过gdb的x命令转储该地址附近内存,发现内存块头部数据偏移了1字节(从魔术数可判断);转储0x7f8bd51a63f0(原地址+1字节)时,头部数据显示正常。
补充:从内存头部数据可确认,该块并非已释放的内存块。
相关代码片段
崩溃发生在以下代码的第125行:
100 static void 101 func (<struct type1> *arg1, <struct type2> **arg2) 102 { 103 <struct type2> *var; 104 var = *arg2; ... ... 125 my_free(var->abc.xyz); ... ... 130 }
结构体定义:
struct type3 { ... void * xyz; // 指向定时器相关对象的指针 ... } struct type2 { ... type3 abc; ... }
已排查情况
- 代码中无
var->abc.xyz被强制转换为char/uchar并递减的操作; - 对
var->abc.xyz的操作仅三类:初始化(malloc分配后赋值)、销毁(调用free释放)、定时器启停/状态检查; - 已排除
var所在内存块的前一个内存块越界:该块仅通过snprintf访问,且传入size已限制在分配内存范围内,无问题; - 怀疑是
type2实例所在内存块的前所有者(线程A)通过悬空指针篡改数据:线程A曾malloc获取Block M,释放后仍持有指针;当线程Bmalloc分配到Block M时,线程A非法写入该块,导致var->abc.xyz被篡改。
求助问题
- 如何确认是否为上述悬空指针导致的问题?
- 还有哪些可能的原因?
内容的提问来源于stack exchange,提问作者Darshan L
相关产品推荐
相关产品推荐

