C++ Runtime Checking: AddressSanitizer & ThreadSanitizer Guide [#41-2]

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

  1. Why runtime checks
  2. AddressSanitizer
  3. ThreadSanitizer
  4. Examples
  5. Common errors
  6. CI integration
  7. Production patterns
  8. 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 ValgrindLeakSanitizer with ASan is lighter for CI.
  • Third-party code — still instrument your glue; rebuild deps with sanitizers when possible.

2. AddressSanitizer

Flags

FlagRole
-fsanitize=addressEnable ASan (compile and link)
-fno-omit-frame-pointerBetter stacks
-gSource lines in reports
-fsanitize=leakLeakSanitizer (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 -O1 or -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: asan build + test, tsan build + 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

ToolFinds
ASanMemory corruption, many leaks
TSanData races

Next: Fuzz testing #41-3

Keywords

ASan, TSan, C++ sanitizer, data race, use-after-free, CI