C++ Runtime Checking: AddressSanitizer & ThreadSanitizer Guide [#41-2]
이 글의 핵심
Instrument builds with ASan/TSan, run tests, and fix reports before they become production crashes.
Introduction: bugs that only appear when you run the code
“It crashes sometimes but we can’t reproduce it”
Static analysis finds suspicious patterns; memory errors (buffer overflow, use-after-free, double-free) and data races depend on scheduling and heap layout. AddressSanitizer (ASan) instruments memory accesses; ThreadSanitizer (TSan) tracks thread operations to detect data races.
Add -fsanitize=address / -fsanitize=thread (plus -g, -fno-omit-frame-pointer) in debug or RelWithDebInfo builds and run your test suite.
Covers: scenarios, ASan/TSan usage, complete examples, common issues, CI wiring, production posture.
Requires: GCC or Clang (MSVC: /fsanitize=address in recent VS). Linux/macOS recommended.
Table of contents
- Why runtime checks
- AddressSanitizer
- ThreadSanitizer
- Examples
- Common errors
- CI integration
- Production patterns
- Summary
1. Why runtime checks
- Prod-only crashes — ASan pinpoints exact access site.
- Heisenbugs under threads — TSan reports racy lines.
- Silent OOB — ASan redzones catch out-of-bounds writes.
- Slow Valgrind — LeakSanitizer with ASan is lighter for CI.
- Third-party code — still instrument your glue; rebuild deps with sanitizers when possible.
2. AddressSanitizer
Flags
| Flag | Role |
|---|---|
-fsanitize=address | Enable ASan (compile and link) |
-fno-omit-frame-pointer | Better stacks |
-g | Source lines in reports |
-fsanitize=leak | LeakSanitizer (often bundled with ASan on Clang) |
What ASan catches
Heap/stack OOB, UAF, double-free, many leaks (LSan).
Overhead
~2× CPU, ~2× memory typical—keep to test/CI builds.
Minimal UAF example
// g++ -std=c++17 -fsanitize=address -fno-omit-frame-pointer -g -o uaf uaf.cpp
#include <iostream>
int main() {
int* p = new int(42);
delete p;
std::cout << *p << "\n"; // UAF — ASan reports
return 0;
}
Use the heap overflow, stack overflow, and LSan examples in this repo’s companion snippets—translate comments locally if needed.
3. ThreadSanitizer
Use -fsanitize=thread (do not mix with ASan in one link). TSan detects unsynchronized reads/writes to the same address where at least one is a write.
Typical fix: mutex, atomic with correct order, or redesign shared state.
4. Examples
Full .cpp samples (race, UAF, overflow) are meant to be copied verbatim into your tree for ASan/TSan experiments.
5. Common errors
- Missing sanitizer at link time.
- Optimized-away frames—use
-O1or-fno-omit-frame-pointer. - TSan noise from benign races in legacy libs—suppress with care.
- ASan on MSVC—check supported scenarios.
6. CI integration
- Separate jobs:
asanbuild + test,tsanbuild + test. - Upload logs on failure.
- Optionally block merge on sanitizer failures.
7. Production patterns
- Sanitizers in staging canaries—not typical latency-sensitive prod.
- Combine with fuzzing, static analysis, canaries.
8. Summary
| Tool | Finds |
|---|---|
| ASan | Memory corruption, many leaks |
| TSan | Data races |
Next: Fuzz testing #41-3
Keywords
ASan, TSan, C++ sanitizer, data race, use-after-free, CI