0

0

c++ Sanitizers大全 c++ ASan/TSan/MSan/UBSan【汇总】

冰火之心

冰火之心

发布时间:2025-12-31 15:56:50

|

218人浏览过

|

来源于php中文网

原创

C++ Sanitizers 是编译时注入的运行时检测工具,用于发现内存错误、数据竞争、未初始化读取和未定义行为;包括 ASan(越界/悬垂指针)、TSan(数据竞争)、MSan(未初始化内存)、UBSan(未定义行为),各具特定启用方式与适用场景。

c++ sanitizers大全 c++ asan/tsan/msan/ubsan【汇总】

C++ Sanitizers 是一组编译时注入的运行时检测工具,专为发现内存错误、数据竞争、未初始化读取和未定义行为而设计。它们不是调试器,也不是静态分析器,而是通过插桩(instrumentation)在程序运行中实时捕获问题,精准定位到源码行,且开销相对可控(尤其 ASan/UBSan 在开发阶段可日常启用)。

ASan(AddressSanitizer):专治内存越界与堆使用后释放

ASan 检测:red">/堆/全局变量的越界读写、use-after-free、double-free、内存泄漏(需配合 -fsanitize=address -fno-omit-frame-pointer -g 并运行时设置 ASAN_OPTIONS=detect_leaks=1

  • 启用方式:编译链接均加 -fsanitize=address -fno-omit-frame-pointer -g;避免内联干扰调试,可追加 -O1-O2-O3 可能隐藏部分报告)
  • 常见误报极少,但会显著增加内存占用(约2倍)和运行时开销(2–3倍),不适合生产环境,但强烈推荐集成进 CI 和本地开发测试流程
  • 遇到 __asan_report_load_n 等符号?说明未链接 ASan 运行时 —— 确保所有 .o/.a/.so 都用相同 Sanitizer 编译,C++ 项目尤其注意第三方静态库是否兼容

TSan(ThreadSanitizer):唯一实用的数据竞争探测器

TSan 通过动态追踪内存访问的 happens-before 关系,精准识别 无锁并发中的竞态条件(data race),包括:多个线程对同一内存地址非原子地读写、未同步的共享变量访问、锁粒度不足等。

  • 启用方式:编译链接加 -fsanitize=thread -fPIE -pie -g;必须启用 PIE(位置无关可执行文件),否则链接失败
  • 不支持 fork() 后的子进程检测;禁用 std::async 默认策略(可能绕过 TSan 插桩),建议显式用 std::launch::deferred 或线程池统一管理
  • 报告中出现 Previous write at ... by thread T1 + Current read at ... by thread T2 即为实锤竞态 —— 不要忽略 “shared variable” 提示,即使你认为“逻辑上不会同时访问”,TSan 以实际执行为准

MSan(MemorySanitizer):揪出未初始化内存的隐性幽灵

MSan 跟踪每个字节的“初始化状态”,捕获对 未初始化栈/堆/全局内存的首次读取(如局部变量声明后未赋值就传给函数、malloc 后未 memset 就读取)。它不检测越界或释放后使用,是 ASan 的互补项。

Red Panda AI
Red Panda AI

AI文本生成图像

下载

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

  • 启用方式:编译链接均加 -fsanitize=memory -fPIE -pie -g -O2;必须开启优化(-O2 最佳),否则大量误报;不兼容 ASan/TSan,不可共存
  • 依赖系统库(如 libc)也经 MSan 编译 —— Linux 上推荐用 Clang 自带的 compiler-rt 运行时,并确保 LD_LIBRARY_PATH 指向其 lib/msan
  • 典型触发场景:结构体含 padding 字段、memcpy 拷贝未初始化内存、C 风格数组声明后仅部分赋值 —— 报告中的 uninitialized value was created by a heap allocation 直接指向 malloc 行

UBSan(UndefinedBehaviorSanitizer):覆盖最广的未定义行为哨兵

UBSan 检测 C++ 标准明确定义为“未定义行为(UB)”的数百种情形,包括:整数溢出、空指针解引用、类型别名违规(strict-aliasing)、违反 const 正确性、移位超界、枚举值越界、虚函数表损坏等

  • 启用方式灵活:默认检测核心 UB(-fsanitize=undefined),也可按需启用子项,如 -fsanitize=signed-integer-overflow,null,shift;推荐开发期全开,CI 中可保留关键项
  • 相比 ASan/TSan,UBSan 开销极小(通常 vptr)需 RTTI,禁用 -fno-rtti 时失效
  • 注意 -fsanitize=undefined 默认不包含浮点异常(如 float-divide-by-zero),需显式添加;遇到 member call on null pointer 却没崩溃?UBSan 已截获并终止,而非让程序继续野跑

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

229

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

433

2024.03.01

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

519

2023.09.20

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

73

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

96

2025.09.18

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

193

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

185

2025.07.04

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

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

48

2025.08.29

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

2

2025.12.31

热门下载

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

精品课程

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

共48课时 | 6.3万人学习

Git 教程
Git 教程

共21课时 | 2.3万人学习

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

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