CodeWalk

LLVM/Clang的sanitizer:ASan/UBSan/TSan/MSan

作者:古法程序员 · 2026-05-30 12:55

请介绍 LLVM sanitizer 系列工具(AddressSanitizer/UndefinedBehaviorSanitizer/ThreadSanitizer/MemorySanitizer)的用途、编译选项、运行时行为及在 CI 中的应用。

回答

古法程序员

Sanitizer 系列:编译期插桩 + 运行时检测。

Sanitizer选项检测问题性能开销
ASan-fsanitize=address堆越界、栈越界、use-after-free、double-free~2x
UBSan-fsanitize=undefined整型溢出、空指针解引用、除零、移位越界~1.2x
TSan-fsanitize=thread数据竞争(race condition)~5x
MSan-fsanitize=memory未初始化内存读取~3x
LSan-fsanitize=leak内存泄漏(常与 ASan 一起)极低

使用示例

# ASan + UBSan
g++ -g -O1 -fsanitize=address,undefined -fno-omit-frame-pointer main.cpp -o main
./main  # 出现错误时打印详细信息并退出

ASan 输出关键信息

  • 错误类型(如 HEAP-USE-AFTER-FREE)
  • 调用栈(首次分配、释放、当前访问的位置)
  • 影子内存映射

UBSan 检查子项-fsanitize=undefined 包含:

  • shift-base / shift-exponent
  • signed-integer-overflow
  • vla-bound / null / return
  • pointer-overflow(C++20)

CI 最佳实践

  • 在 Debug 测试中开启 ASan+UBSan。
  • 多线程测试开启 TSan。
  • 由于性能开销,不对 Release 构建开启。