0

0

如何使用AddressSanitizer(ASan)检测c++内存错误? (编译选项配置)

尼克

尼克

发布时间:2026-01-18 12:13:33

|

706人浏览过

|

来源于php中文网

原创

AddressSanitizer需正确编译选项才能生效:必须加-fsanitize=address、-g、-O1及以上优化级、-fno-omit-frame-pointer,且编译和链接均需该选项;否则无法捕获内存错误。

如何使用addresssanitizer(asan)检测c++内存错误? (编译选项配置)

AddressSanitizer 能在运行时捕获绝大多数内存错误,但前提是编译器必须插桩(instrument)你的代码——这完全依赖正确的编译选项,缺一不可。

必须启用的 GCC/Clang 编译选项

ASan 不是链接期工具,也不是运行时加载的库,它靠编译器在生成汇编前插入检查逻辑。漏掉任一关键选项,就等于没开 ASan。

  • -fsanitize=address 是核心开关,告诉编译器启用 ASan 插桩;不加这个,其他都无效
  • -g 必须带上,否则报错时只能看到地址,看不到源码行号和变量名
  • -O1 或更高优化级(推荐 -O2)是安全的,ASan 已适配;但 -O0 会导致部分越界检测失效(如上缓冲区溢出可能被绕过)
  • -fno-omit-frame-pointer 强烈建议加上,能提升栈追踪准确性,尤其在内联函数或尾调用场景下

链接时也要传同样的 -fsanitize=address

如果你分步编译(g++ -c)再链接(g++ -o),容易只在编译阶段加了 ASan、链接时却漏掉。最终可执行文件不会包含 ASan 运行时,运行时也就不会报错。

正确做法是:所有 g++clang++ 命令(包括链接命令)都带 -fsanitize=address。例如:

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

AI at Meta
AI at Meta

Facebook 旗下的AI研究平台

下载
g++ -fsanitize=address -g -O2 -fno-omit-frame-pointer -c main.cpp -o main.o
g++ -fsanitize=address main.o -o program

更简单的是一步到位:

g++ -fsanitize=address -g -O2 -fno-omit-frame-pointer main.cpp -o program

常见误配导致“没报错”或“报错位置不准”

不是所有内存问题都能被 ASan 捕获,但多数“没报错”其实是配置没生效。典型陷阱有:

  • 混用不同版本的 ASan 运行时:比如用 Clang 编译但用系统 GCC 的 libasan.so,会触发 undefined symbol: __asan_option_detect_stack_use_after_return 类错误
  • 静态链接禁用了 ASan:加了 -static 会跳过 ASan 运行时库,必须显式链接 -static-libasan(Clang)或确保 libasan.so 可被找到
  • 环境变量干扰:如果设置了 ASAN_OPTIONS=detect_stack_use_after_return=false 却忘了开启,栈上 UAF 就不会被检测
  • C++ 异常与 ASan 冲突:某些旧版 GCC(如 7.5 之前)在 -fexceptions + ASan 下可能崩溃,此时加 -fno-exceptions 可绕过(但会丢异常语义)

运行时行为与关键环境变量

ASan 启动后默认行为已足够实用,但几个环境变量能帮你定位更隐蔽的问题:

  • ASAN_OPTIONS=abort_on_error=1:让程序在首次报错时直接 abort(),避免后续误报干扰
  • ASAN_OPTIONS=detect_stack_use_after_return=true:启用栈内存释放后访问检测(默认关闭,因有性能开销)
  • ASAN_OPTIONS=allocator_may_return_null=1:让 new 在 OOM 时返回 nullptr 而非抛异常,便于测试空指针路径
  • 注意:这些变量需在运行前设置,export ASAN_OPTIONS=...,不能写进代码里

ASan 报错信息里的 READ of size Xheap-use-after-free 看似明确,但真正难的是确认哪一行分配了那块内存——这时候 -g 和未被优化掉的帧指针就不是可选项,而是必需项。

相关专题

更多
堆和栈的区别
堆和栈的区别

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

390

2023.07.18

堆和栈区别
堆和栈区别

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

572

2023.08.10

空指针异常处理
空指针异常处理

本专题整合了空指针异常解决方法,阅读专题下面的文章了解更多详细内容。

22

2025.11.16

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

4843

2023.07.31

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

2971

2024.08.14

网页undefined啥意思
网页undefined啥意思

本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

196

2025.12.25

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

42

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

74

2026.01.16

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

23

2026.01.16

热门下载

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

精品课程

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

共58课时 | 3.8万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

ASP 教程
ASP 教程

共34课时 | 3.7万人学习

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

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