AddressSanitizer(ASan)是Clang和GCC内置的高速内存错误检测工具,可捕获越界访问、Use-After-Free等错误;启用需编译和链接均加-fsanitize=address及-fno-omit-frame-pointer,泄漏检测需额外加,leak。
AddressSanitizer(ASan)是Clang和GCC内置的高速内存错误检测工具,能精准捕获堆/栈/全局区的越界访问、Use-After-Free、双重释放、内存泄漏(需配合LeakSanitizer)等常见C++问题。开启它不需改代码,只需编译时加几个标志,运行时就能实时报错并给出调用栈。
以g++或clang++为例,必须同时开启编译和链接阶段的ASan支持:
-fsanitize=address -fno-omit-frame-pointer(后者保证栈回溯准确)-fsanitize=address(否则链接失败或检测失效)-O1 或 -O2(ASan在优化后仍有效;但避免 -O3 可能导致误报)完整命令示例:g++ -fsanitize=address -fno-omit-frame-pointer -O1 -g main.cpp -o main
一旦触发内存错误,ASan会中止程序并打印带颜色的详细报告。重点关注以下几部分:
heap-buffer-overflow、use-after-free、stack-use-after-return
READ of size 4 at 0x602000000014
allocated by thread T0 here: 和 freed by thread T0 here: 对应的源码行-g 编译)小技巧:设置环境变量 ASAN_OPTIONS=abort_on_error=1 让程序在报错时直接产生 core dump,方便用 gdb ./main core 进一步分析。
默认ASan不检查内存泄漏,需显式启用 LeakSanitizer(LSan),且行为可定制:
-fsanitize=address,leak(注意是逗号分隔,非空格)ASAN_OPTIONS=detect_odr_violation=0:suppressions=./asan.supp
asan.supp 示例:intercepted_function:malloc
leak:my_legacy_module.so
注意:LSan在程序退出时扫描未释放内存,因此需确保main正常返回(而非直接exit或kill)。
ASan强大但有局限,提前了解可少走弯路:
-fsanitize=address -fstack-protector-strong 补充防护不复杂但容易忽略——只要记住“编译链都加 -fsanitize=address,运行看报错栈,泄漏加 ,leak”,大部分C++内存问题都能一眼揪出。