sanitizers
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSanitizers
Sanitizer工具集
Purpose
用途
Guide agents through choosing, enabling, and interpreting compiler runtime sanitizers for finding memory errors, undefined behaviour, data races, and memory leaks.
指导开发者选择、启用编译器运行时Sanitizer工具,并解读其检测结果,以发现内存错误、未定义行为、数据竞争及内存泄漏问题。
Triggers
触发场景
- "My program has a memory error — which sanitizer do I use?"
- "How do I enable ASan?"
- "How do I interpret an ASan/UBSan/TSan report?"
- "ASan says heap-buffer-overflow — what does that mean?"
- "How do I suppress false positives in sanitizers?"
- "Can I use sanitizers in CI?"
- “我的程序出现内存错误,应该使用哪款Sanitizer?”
- “如何启用ASan?”
- “如何解读ASan/UBSan/TSan的检测报告?”
- “ASan提示heap-buffer-overflow,这是什么意思?”
- “如何抑制Sanitizer的误报?”
- “能否在CI中使用Sanitizer?”
Workflow
操作流程
1. Decision tree: which sanitizer?
1. 选型决策树:选择合适的Sanitizer
Bug class?
├── Memory OOB, use-after-free, double-free → AddressSanitizer (ASan)
├── Stack OOB, global OOB → ASan (all three covered)
├── Uninitialised reads → MemorySanitizer (MSan, Clang only, requires all-clang build)
├── Undefined behaviour (int overflow, null deref, bad cast) → UBSan
├── Data races (multi-thread) → ThreadSanitizer (TSan)
├── Memory leaks only → LeakSanitizer (LSan, standalone or via ASan)
└── Multiple classes → ASan + UBSan (common combo); cannot combine with TSan or MSanBug类别?
├── 内存越界、释放后使用、重复释放 → AddressSanitizer (ASan)
├── 栈越界、全局变量越界 → ASan(可覆盖这三类问题)
├── 未初始化内存读取 → MemorySanitizer (MSan,仅支持Clang,需全Clang编译构建)
├── 未定义行为(整数溢出、空指针解引用、错误类型转换) → UBSan
├── 数据竞争(多线程场景) → ThreadSanitizer (TSan)
├── 仅检测内存泄漏 → LeakSanitizer (LSan,可独立使用或通过ASan启用)
└── 多类问题并存 → ASan + UBSan(常用组合);不可与TSan或MSan同时使用2. AddressSanitizer (ASan)
2. AddressSanitizer (ASan)
bash
undefinedbash
undefinedGCC or Clang
GCC 或 Clang
gcc -fsanitize=address -fno-omit-frame-pointer -g -O1 -o prog main.c
gcc -fsanitize=address -fno-omit-frame-pointer -g -O1 -o prog main.c
Or
或者
clang -fsanitize=address -fno-omit-frame-pointer -g -O1 -o prog main.c
Runtime options (via `ASAN_OPTIONS`):
```bash
ASAN_OPTIONS=detect_leaks=1:abort_on_error=1:log_path=/tmp/asan.log ./prog | Effect |
|---|---|
| Enable LeakSanitizer (default 1 on Linux) |
| Call |
| Write report to file |
| Symbolize addresses (needs |
| More accurate stacks (slower) |
| Delay reuse of freed memory |
Interpreting ASan output:
==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000050
READ of size 4 at 0x602000000050 thread T0
#0 0x401234 in foo /home/user/src/main.c:15
#1 0x401567 in main /home/user/src/main.c:42
0x602000000050 is located 0 bytes after a 40-byte region
[0x602000000028, 0x602000000050) allocated at:
#0 0x7f12345 in malloc ...
#1 0x401234 in main /home/user/src/main.c:10Reading: the top frame in is the access site; the stack shows the allocation. The region is 40 bytes at and the access is at = one byte past the end (classic off-by-one).
WRITE/READallocated at[start, end)endclang -fsanitize=address -fno-omit-frame-pointer -g -O1 -o prog main.c
运行时选项(通过`ASAN_OPTIONS`设置):
```bash
ASAN_OPTIONS=detect_leaks=1:abort_on_error=1:log_path=/tmp/asan.log ./prog | 作用 |
|---|---|
| 启用LeakSanitizer(Linux下默认值为1) |
| 调用 |
| 将检测报告写入指定文件 |
| 对内存地址进行符号化(需将 |
| 生成更精确的调用栈(速度较慢) |
| 延迟复用已释放的内存 |
解读ASan输出结果:
==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000050
READ of size 4 at 0x602000000050 thread T0
#0 0x401234 in foo /home/user/src/main.c:15
#1 0x401567 in main /home/user/src/main.c:42
0x602000000050 is located 0 bytes after a 40-byte region
[0x602000000028, 0x602000000050) allocated at:
#0 0x7f12345 in malloc ...
#1 0x401234 in main /home/user/src/main.c:10解读:部分的顶层栈帧是错误访问的位置;栈帧显示内存分配的位置。该内存区域大小为40字节,范围是,而错误访问发生在位置(典型的数组越界1字节问题)。
WRITE/READallocated at[start, end)end3. UndefinedBehaviorSanitizer (UBSan)
3. UndefinedBehaviorSanitizer (UBSan)
bash
gcc -fsanitize=undefined -g -O1 -o prog main.cbash
gcc -fsanitize=undefined -g -O1 -o prog main.cMore complete: add specific checks
更全面的检测:添加特定检查项
gcc -fsanitize=undefined,integer -g -O1 -o prog main.c
Common UBSan checks:
- `signed-integer-overflow`
- `unsigned-integer-overflow` (not in `undefined` by default)
- `null` — null pointer dereference
- `bounds` — array index OOB (compile-time knowable bounds)
- `alignment` — misaligned pointer access
- `float-cast-overflow` — float-to-int conversion overflow
- `vptr` — C++ vtable type mismatch
- `shift-exponent` — shift >= bit width
```bashgcc -fsanitize=undefined,integer -g -O1 -o prog main.c
常见UBSan检查项:
- `signed-integer-overflow`:有符号整数溢出
- `unsigned-integer-overflow`:无符号整数溢出(默认不包含在`undefined`检查集中)
- `null`:空指针解引用
- `bounds`:数组索引越界(编译期可确定边界的情况)
- `alignment`:指针访问未对齐
- `float-cast-overflow`:浮点转整数时溢出
- `vptr`:C++虚表类型不匹配
- `shift-exponent`:移位操作的指数大于等于数据位宽
```bashEnable everything including integer overflow
启用所有检查项,包括整数溢出
gcc -fsanitize=undefined
-fsanitize=signed-integer-overflow,unsigned-integer-overflow,float-cast-overflow
-fno-sanitize-recover=all \ # abort instead of continue -g -O1 -o prog main.c
-fsanitize=signed-integer-overflow,unsigned-integer-overflow,float-cast-overflow
-fno-sanitize-recover=all \ # abort instead of continue -g -O1 -o prog main.c
`-fno-sanitize-recover=all`: makes UBSan abort on first error (important for CI).
**Interpreting UBSan output:**src/main.c:15:12: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
undefinedgcc -fsanitize=undefined
-fsanitize=signed-integer-overflow,unsigned-integer-overflow,float-cast-overflow
-fno-sanitize-recover=all \ # 检测到错误即终止程序,而非继续执行 -g -O1 -o prog main.c
-fsanitize=signed-integer-overflow,unsigned-integer-overflow,float-cast-overflow
-fno-sanitize-recover=all \ # 检测到错误即终止程序,而非继续执行 -g -O1 -o prog main.c
`-fno-sanitize-recover=all`:让UBSan在检测到第一个错误时就终止程序(在CI环境中非常重要)。
**解读UBSan输出结果:**src/main.c:15:12: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
undefined4. ThreadSanitizer (TSan)
4. ThreadSanitizer (TSan)
bash
undefinedbash
undefinedClang or GCC (GCC ≥ 4.8)
Clang 或 GCC(GCC 版本≥4.8)
clang -fsanitize=thread -g -O1 -o prog main.c
clang -fsanitize=thread -g -O1 -o prog main.c
TSan is incompatible with ASan and MSan
TSan 与 ASan、MSan 不兼容
**Interpreting TSan output:**WARNING: ThreadSanitizer: data race (pid=12345)
Write of size 4 at 0x7f... by thread T2:
#0 increment /home/user/src/counter.c:8
Previous read of size 4 at 0x7f... by thread T1:
#0 read_counter /home/user/src/counter.c:3
undefined
**解读TSan输出结果:**WARNING: ThreadSanitizer: data race (pid=12345)
Write of size 4 at 0x7f... by thread T2:
#0 increment /home/user/src/counter.c:8
Previous read of size 4 at 0x7f... by thread T1:
#0 read_counter /home/user/src/counter.c:3
undefined5. MemorySanitizer (MSan)
5. MemorySanitizer (MSan)
MSan detects reads of uninitialised memory. Clang only. Requires all-instrumented build (no mixing of MSan and non-MSan objects).
bash
clang -fsanitize=memory -fno-omit-frame-pointer -g -O1 -o prog main.cMSan用于检测未初始化内存的读取操作。仅支持Clang,需全 instrumentation 构建(不能混合使用MSan编译和非MSan编译的目标文件)。
bash
clang -fsanitize=memory -fno-omit-frame-pointer -g -O1 -o prog main.cWith origin tracking (slower but shows where uninit value came from)
启用来源追踪(速度较慢,但可显示未初始化值的来源)
clang -fsanitize=memory -fsanitize-memory-track-origins=2 -g -O1 -o prog main.c
System libraries must be rebuilt with MSan or substituted with MSan-instrumented wrappers. Use `msan-libs` toolchain from LLVM.clang -fsanitize=memory -fsanitize-memory-track-origins=2 -g -O1 -o prog main.c
系统库必须使用MSan重新编译,或替换为经过MSan instrumentation的包装库。可使用LLVM提供的`msan-libs`工具链。6. ASan + UBSan combined
6. ASan + UBSan 组合使用
bash
gcc -fsanitize=address,undefined -fno-sanitize-recover=all \
-fno-omit-frame-pointer -g -O1 -o prog main.cDo not combine with TSan or MSan.
bash
gcc -fsanitize=address,undefined -fno-sanitize-recover=all \
-fno-omit-frame-pointer -g -O1 -o prog main.c不可与TSan或MSan同时使用。
7. Suppressions
7. 抑制误报
bash
undefinedbash
undefinedASan suppression file
ASan 抑制文件
cat > asan.supp << 'EOF'
cat > asan.supp << 'EOF'
Suppress leaks from OpenSSL init
抑制OpenSSL初始化时的内存泄漏误报
leak:CRYPTO_malloc
EOF
LSAN_OPTIONS=suppressions=asan.supp ./prog
leak:CRYPTO_malloc
EOF
LSAN_OPTIONS=suppressions=asan.supp ./prog
UBSan suppression
UBSan 抑制文件
cat > ubsan.supp << 'EOF'
signed-integer-overflow:third_party/fast_math.c
EOF
UBSAN_OPTIONS=suppressions=ubsan.supp:print_stacktrace=1 ./prog
undefinedcat > ubsan.supp << 'EOF'
signed-integer-overflow:third_party/fast_math.c
EOF
UBSAN_OPTIONS=suppressions=ubsan.supp:print_stacktrace=1 ./prog
undefined8. CMake integration
8. CMake 集成
cmake
option(SANITIZE "Enable sanitizers" OFF)
if(SANITIZE)
set(san_flags -fsanitize=address,undefined -fno-sanitize-recover=all
-fno-omit-frame-pointer -g -O1)
add_compile_options(${san_flags})
add_link_options(${san_flags})
endif()cmake
option(SANITIZE "Enable sanitizers" OFF)
if(SANITIZE)
set(san_flags -fsanitize=address,undefined -fno-sanitize-recover=all
-fno-omit-frame-pointer -g -O1)
add_compile_options(${san_flags})
add_link_options(${san_flags})
endif()9. CI integration
9. CI 集成
yaml
undefinedyaml
undefinedGitHub Actions example
GitHub Actions 示例
-
name: Build with ASan+UBSan run: | cmake -S . -B build -DSANITIZE=ON cmake --build build -j$(nproc)
-
name: Run tests under sanitizers run: | ASAN_OPTIONS=abort_on_error=1:detect_leaks=1
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1
ctest --test-dir build -j$(nproc) --output-on-failure
For a quick flag reference, see [references/flags.md](references/flags.md).
For report interpretation examples, see [references/reports.md](references/reports.md).-
name: Build with ASan+UBSan run: | cmake -S . -B build -DSANITIZE=ON cmake --build build -j$(nproc)
-
name: Run tests under sanitizers run: | ASAN_OPTIONS=abort_on_error=1:detect_leaks=1
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1
ctest --test-dir build -j$(nproc) --output-on-failure
快速参考编译选项可查看 [references/flags.md](references/flags.md)。
检测报告解读示例可查看 [references/reports.md](references/reports.md)。Related skills
相关技能
- Use for Memcheck when ASan is unavailable
skills/profilers/valgrind - Use to auto-generate inputs that trigger sanitizer errors
skills/runtimes/fuzzing - Use or
skills/compilers/gccfor build flag contextskills/compilers/clang
- 当ASan不可用时,使用的Memcheck工具
skills/profilers/valgrind - 使用自动生成可触发Sanitizer错误的测试输入
skills/runtimes/fuzzing - 如需编译选项相关上下文,可使用或
skills/compilers/gcc技能skills/compilers/clang