0

0

c++ ASan怎么用 c++ AddressSanitizer内存检查【工具】

尼克

尼克

发布时间:2025-12-27 15:56:56

|

325人浏览过

|

来源于php中文网

原创

AddressSanitizer(ASan)是Clang/GCC提供的编译期插桩内存检测工具,可快速发现缓冲区溢出、use-after-free等错误,需编译链接均加-fsanitize=address、禁用高优化并加-g,运行时报错含详细堆栈与内存信息。

c++ asan怎么用 c++ addresssanitizer内存检查【工具】

AddressSanitizer(ASan)是 Clang 和 GCC 提供的内存错误检测工具,能快速发现堆缓冲区溢出、use-after-free、double-free、内存泄漏(需额外开启)等常见问题。它不是运行时库,而是编译期插桩 + 运行时检测,开销约 2×,但远比 Valgrind 快。

编译时启用 ASan

关键是在编译和链接阶段都加上 -fsanitize=address,并建议禁用优化(或至少不用 -O2 及以上),否则可能漏报或误报:

  • Clang:clang++ -fsanitize=address -g -O1 main.cpp -o main
  • GCC(≥4.8):g++ -fsanitize=address -g -O1 main.cpp -o main
  • 务必加 -g,否则报错时看不到源码行号
  • 避免 -O2/-O3:优化可能把检测逻辑优化掉,或导致栈变量生命周期判断不准

运行时行为与典型报错

程序运行后一旦触发非法内存访问,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 行为,适合不同场景:

Explainpaper
Explainpaper

阅读学术论文的更好方法,你的学术论文阅读助手。

下载

立即学习C++免费学习笔记(深入)”;

  • ASAN_OPTIONS=abort_on_error=1:出错直接 abort,方便用 gdb 调试(gdb ./mainrun → 崩溃后 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() 手动标记

CMake 项目中集成 ASan

在 CMakeLists.txt 中添加条件编译支持,避免每次手动改命令:

  • 启用方式:cmake -DCMAKE_CXX_FLAGS="-fsanitize=address -g -O1" -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" ..
  • 或在 CMakeLists.txt 内加:
    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} -fsanitize=address")
    endif()
  • 注意:CMake 的 add_compile_options 不影响链接器标志,必须单独设 CMAKE_EXE_LINKER_FLAGS

相关专题

更多
scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

184

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

259

2023.10.25

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

47

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

94

2025.10.23

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

363

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

558

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

363

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

558

2023.08.10

ip地址修改教程大全
ip地址修改教程大全

本专题整合了ip地址修改教程大全,阅读下面的文章自行寻找合适的解决教程。

27

2025.12.26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.8万人学习

ASP 教程
ASP 教程

共34课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号