AddressSanitizer(ASan)是Clang/GCC提供的编译期插桩内存检测工具,可快速发现缓冲区溢出、use-after-free等错误,需编译链接均加-fsanitize=address、禁用高优化并加-g,运行时报错含详细堆栈与内存信息。
AddressSanitizer(ASan)是 Clang 和 GCC 提供的内存错误检测工具,能快速发现堆栈缓冲区溢出、use-after-free、double-free、内存泄漏(需额外开启)等常见问题。它不是运行时库,而是编译期插桩 + 运行时检测,开销约 2×,但远比 Valgrind 快。
关键是在编译和链接阶段都加上 -fsanitize=address,并建议禁用优化(或至少不用 -O2 及以上),否则可能漏报或误报:
clang++ -fsanitize=address -g -O1 main.cpp -o main
g++ -fsanitize=address -g -O1 main.cpp -o main
程序运行后一旦触发非法内存访问,ASan 会立即终止进程,并打印带堆栈、内存布局、访问地址、对象起源等信息的详细报告:
ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000001c
ERROR: AddressSanitizer: use-after-free on address 0x602000000030
allocated by thread T0 here:)、访问位置、以及附近内存快照ASAN_OPTIONS=detect_leaks=1 ./main
通过环境变量可微调 ASan 行为,适合不同场景:
ASAN_OPTIONS=abort_on_error=1:出错直接 abort,方便用 gdb 调试(gdb ./main → run → 崩溃后 bt)ASAN_OPTIONS=disable_coredump=0:允许生成 core dump,便于事后分析ASAN_OPTIONS=allocator_may_return_null=1:让 new 失败时返回 nullptr 而非抛异常(兼容旧代码)__asan_poison_memory_region() / __asan_unpoison_memory_region() 手动标记在 CMakeLists.txt 中添加条件编译支持,避免每次手动改命令:
cmake -DCMAKE_CXX_FLAGS="-fsanitize=address -g -O1" -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" ..
if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang|GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -g -O1")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsa
nitize=address")
endif()
add_compile_options 不影响链接器标志,必须单独设 CMAKE_EXE_LINKER_FLAGS