C++ Sanitizers 是编译时注入的运行时检测工具,用于发现内存错误、数据竞争、未初始化读取和未定义行为;包括 ASan(越界/悬垂指针)、TSan(数据竞争)、MSan(未初始化内存)、UBSan(未定义行为),各具特定启用方式与适用场景。
C++ Sanitizers 是一组编译时注入的运行时检测工具,专为发现内存错误、数据竞争、未初始化读取和未定义行为而设计。它们不是调试器,也不是静态分析器,而是通过插桩(instrumentation)在程序运行中实时捕获问题,精准定位到源码行,且开销相对可控(尤其 ASan/UBSan 在开发阶段可日常启用)。
ASan 检测:栈/堆/全局变量的越界读写、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 通过动态追踪内存访问的 happens-before 关系,精准识别 无锁并发中的竞态条件(data race),包括:多个线程对同一内存地址非原子地读写、未同步的共享变量访问、锁粒度不足等。
-fsanitize=thread -fPIE -pie -g;必须启用 PIE(位置无关可执行文件),否则链接失败std::async 默认策略(可能绕过 TSan 插桩),建议显式用 std::launch::deferred 或线程池统一管理Previous write at ... by thread T1 + Current read at ... by thread T2 即为实锤竞态 —— 不要忽略 “shared variable” 提示,即使你认为“逻辑上不会同时访问”,TSan 以实际执行为准MSan 跟踪每个字节的“初始化状态”,捕获对 未初始化栈/堆/全局内存的首次读取(如局部变量声明后未赋值就传给函数、malloc 后未 memset 就读取)。它不检测越界或释放后使用,是 ASan 的互补项。
-fsanitize=memory -fPIE -pie -g -O2;必须开启优化(-O2 最佳),否则大量误报;不兼容 ASan/TSan,不可共存compiler-rt 运行时,并确保 LD_LIBRARY_PATH 指向其 lib/msan
uninitialized value was created by a heap allocation 直接指向 malloc 行UBSan 检测 C++ 标准明确定义为“未定义行为(UB)”的数百种情形,包括:整数溢出、空指针解引用、类型别名违规(strict-aliasing)、违反 const 正确性、移位超界、枚举值越界、虚函数表损坏等。
-fsanitize=undefined),也可按需启用子项,如 -fsanitize=signed-integer-overflow,null,shift;推荐开发期全开,CI 中可保留关键项-fno-rtti 时失效-fsanitize=undefined 默认不包含浮点异常(如 float-divide-by-zero),需显式添加;遇到 member call on null pointer 却没崩溃?UBSan 已截获并终止,而非让程序继续野跑