✅ 什么是 AddressSanitizer(ASan)?
AddressSanitizer(ASan) 是 GCC 和 Clang 提供的一种快速内存错误检测工具,可检测:
堆/栈/全局变量的 缓冲区溢出(buffer overflow)
释放后使用(use-after-free)
重复释放(double free)
内存泄漏(需额外开启)
返回栈地址(return-stack-address) 等
⚠️ 注意:ASan 会显著增加内存开销(约 2x)和降低运行速度(约 2–3x),仅用于开发/测试阶段。
🛠 使用步骤(CMake 项目)
1️⃣ 设置编译器标志(启用 ASan)
在编译前设置环境变量:
bash
启用 AddressSanitizer + 调试信息 + 禁用优化(便于定位)
export CFLAGS=“-fsanitize=address -g -O0 -fno-omit-frame-pointer”
export CXXFLAGS=“-fsanitize=address -g -O0 -fno-omit-frame-pointer”
export LDFLAGS=“-fsanitize=address”
💡 说明:
-fsanitize=address:启用 ASan
-g:包含调试符号(让堆栈可读)
-O0:关闭优化(避免变量被优化掉,影响调试)
-fno-omit-frame-pointer:保留帧指针,提升堆栈回溯准确性
2️⃣ 正常配置并编译项目(以 CMake 为例)
bash
清理旧构建(推荐)
rm -rf build/
配置项目(保留你的其他选项,如 -DACL=ON)
cmake -B build -DACL=ON .
编译
cd build && make -j$(nproc)
✅ 所有可执行文件和共享库都会自动链接 ASan 运行时。
3️⃣ 设置 ASan 运行时选项(可选但推荐)
bash
启用内存泄漏检测 + 出错立即终止 + 打印统计信息
export ASAN_OPTIONS=“detect_leaks=1:halt_on_error=1:abort_on_error=1:print_stats=1”
常用 ASAN_OPTIONS 参数说明:
选项 作用
detect_leaks=1 检测程序退出时的内存泄漏(Linux 默认开启,macOS 需显式开启)
halt_on_error=1 首次检测到错误时立即停止程序
abort_on_error=1 出错时调用 abort()(便于 core dump 或 gdb 调试)
print_stats=1 程序结束时打印 ASan 内存使用统计
symbolize=1 自动符号化解析(需 -g,通常默认开启)
📌 提示:多个选项用冒号 : 分隔,不要加空格。
4️⃣ 运行程序并观察输出
bash
./your_program
如果存在内存错误,ASan 会输出类似:
text
12345ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000010 at pc 0x555555555123 bp 0x7fffffffeabc sp 0x7fffffffeabd
WRITE of size 1 at 0x602000000010 thread T0
#0 0x555555555122 in main /path/to/main.c:10
#1 0x7ffff7a05d09 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26d09)
#2 0x555555555049 in _start (/path/to/your_program+0x1049)
0x602000000010 is located 0 bytes to the right of 16-byte region [0x602000000000,0x602000000010)
allocated by thread T0 here:
#0 0x7ffff7e9b9c7 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10b9c7)
#1 0x555555555101 in main /path/to/main.c:8
#2 0x7ffff7a05d09 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26d09)
SUMMARY: AddressSanitizer: heap-buffer-overflow /path/to/main.c:10 in main
…
✅ 包含:
错误类型(heap-buffer-overflow)
出错地址和访问大小
完整调用栈(带源码行号)
内存分配位置
🧹 清理与注意事项
❌ 不要将 ASan 版本用于生产环境!
性能差、内存占用高
依赖 libasan.so 运行时
🔁 如何关闭 ASan?
只需重新编译不带 -fsanitize=address 即可:
bash
unset CFLAGS CXXFLAGS LDFLAGS
cmake -B build …
make
🐞 调试技巧
结合 gdb:先运行程序触发 ASan 错误,记录出错地址;或使用 abort_on_error=1 后用 gdb ./program core 分析。
若无符号:确保编译时加了 -g
✅ 总结:ASan 使用流程
步骤 命令
- 设置编译标志 export CFLAGS=… CXXFLAGS=… LDFLAGS=…
- 重新构建 cmake -B build … && cd build && make
- 设置运行选项 export ASAN_OPTIONS=“detect_leaks=1:halt_on_error=1:…”
- 运行测试 ./your_program
- 分析输出 查看错误类型、堆栈、分配历史



1529

被折叠的 条评论
为什么被折叠?



