ASan报错中heap-use-after-free表示释放后使用指针,stack-buffer-overflow表示局部数组越界;需结合READ/WRITE、地址、源码行号及调用栈精准定位。

直接看错误信息里的 heap-use-after-free、stack-buffer-overflow 这类关键词,基本就能定位问题类型;不需要先猜,也不用翻源码找半天。
看懂 ASan 报错格式和关键字段
ASan 的报错不是乱打的,每行都有明确含义。重点盯住三块:
-
ERROR: AddressSanitizer: xxx on address 0x...—— 错误类型决定后续排查方向(比如heap-use-after-free就是 free 后还用了指针,stack-buffer-overflow是局部数组越界) -
READ of size X at ...或WRITE of size X...—— 是读还是写?改的是几个字节?能帮你判断是否是结构体成员偏移错、类型强转失误 -
#0 0x... in main at foo.c:42—— 这是真正出事的那行代码,不是 malloc 那行,也不是传参那行,就是解引用/越界访问发生的那一行
注意:如果调用栈里出现 __interceptor_malloc 或 __interceptor_free,说明 ASan 已成功拦截了标准库内存操作,你看到的堆栈是可信的。
Clang 22.1.3 Windows 64 位历史版本安装包,适合旧项目兼容、LLVM/Clang 工具链回退、编译行为对比、链接问题复现和 C/C++ 构建环境维护。
常见错误类型对应的操作路径
不同错误类型,修复思路差异很大,不能一概而论:
-
heap-use-after-free:立刻检查报错行附近有没有free/delete调用,再往上追溯这个指针是不是在别处被释放过;特别注意循环中反复free同一变量、或函数返回后仍持有已释放内存的指针 -
heap-buffer-overflow:检查报错行的数组下标、memcpy长度、strncpy第三个参数是否小于目标缓冲区大小;注意sizeof(arr)对指针无效,只对栈上数组有效 -
stack-buffer-overflow:典型如char buf[32]; strcpy(buf, big_str);;ASan 会标出溢出多少字节,结合源码算一下实际复制长度和目标容量差多少 -
global-buffer-overflow:全局数组越界,比如int g_arr[10]; g_arr[15] = 1;;这类容易被忽略,因为不触发段错误也能跑,但会污染相邻全局变量
为什么加了 -fsanitize=address 还没报错?
不是所有内存问题都会被 ASan 捕获,漏报通常有这几个硬性原因:
- 没加
-fno-omit-frame-pointer:调用栈可能截断,导致报错位置指向汇编指令而非 C 行号 - 优化级别太高(比如
-O2以上):编译器可能把有问题的代码整个优化掉,或者内联后让 ASan 插桩失效;调试阶段坚持用-O1或-O0 - 没加
-g:报错里只有地址没有文件名和行号,等于白跑;哪怕 Release 构建也要保留调试符号用于 ASan - 泄漏检测没显式启用:
detect_leaks=1在较老版本 Clang/GCC 中默认关闭,必须设环境变量:ASAN_OPTIONS=detect_leaks=1 ./your_program
还有一个隐蔽点:ASan 不检测未初始化内存读取(那是 MemorySanitizer 的活),也**不检查栈上变量的未定义值使用**——它只管“访问是否越界”或“内存是否已释放”,不管值本身合不合理。

















