LLVM Built-in Sanitizers: A Complete Guide to Enabling AddressSanitizer

AddressSanitizer detects memory errors like use-after-free and buffer overflows when you compile C++ code with the -fsanitize=address flag and link against the compiler-rt runtime library.

The llvm/llvm-project repository provides a suite of runtime sanitizers integrated directly into the Clang compiler driver. These tools instrument your code during compilation to catch bugs at runtime, with the complete catalog defined in clang/include/clang/Basic/Sanitizers.def.

What Are LLVM Built-in Sanitizers?

LLVM built-in sanitizers are runtime checking tools embedded in the compiler toolchain. Each sanitizer is identified by a string passed to the -fsanitize= command-line option, which the driver expands into specific LLVM IR instrumentation passes and links the matching runtime library from compiler-rt.

The canonical list resides in clang/include/clang/Basic/Sanitizers.def, where each entry follows the pattern SANITIZER("name", Identifier). You activate any sanitizer by passing its identifier to Clang.

Common built-in sanitizers include:

  • address: Detects out-of-bounds heap/stack/global accesses, use-after-free, and double-free (AddressSanitizer).
  • thread: Identifies data races using ThreadSanitizer.
  • memory: Catches uninitialized memory reads with MemorySanitizer.
  • leak: Finds memory leaks via LeakSanitizer (often bundled with ASan).
  • undefined: Enables UndefinedBehaviorSanitizer checks for alignment violations, array-bounds, and integer overflow.
  • hwaddress: Hardware-assisted AddressSanitizer using ARM Memory Tagging Extension (MTE).

How to Enable AddressSanitizer

Enabling AddressSanitizer requires a Clang built with the compiler-rt runtime and the correct compilation flags.

Build Requirements

First, ensure your LLVM/Clang build includes the sanitizers runtime. The sanitizer libraries live in the compiler-rt subproject. Configure CMake with:

cmake -DCMAKE_BUILD_TYPE=Release \
      -DLLVM_ENABLE_PROJECTS="clang" \
      -DLLVM_ENABLE_RUNTIMES="compiler-rt" \
      /path/to/llvm-project/llvm

This builds the libclang_rt.asan runtime library required for instrumentation.

Compilation Flags

Compile your code with -fsanitize=address. Clang automatically injects instrumentation from llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp and links the ASan runtime from compiler-rt/lib/asan/.

Use these flags for optimal results:

clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer -c foo.cpp
clang++ -g -fsanitize=address foo.o -o foo

The -fno-omit-frame-pointer flag ensures accurate stack traces, while -O1 maintains reasonable performance without optimizing away the code you want to check.

Runtime Behavior and Configuration

When you run an ASan-instrumented binary, the runtime prints detailed error reports to stderr and aborts immediately on the first detected error. Expect approximately a 2× slowdown and increased memory usage proportional to allocation sizes.

Customize behavior via the ASAN_OPTIONS environment variable:

ASAN_OPTIONS=detect_stack_use_after_return=1:symbolize=0 ./program

Alternatively, define __asan_default_options() in your source code to set compile-time defaults.

Symbolizing Stack Traces

For readable file and line numbers, set ASAN_SYMBOLIZER_PATH to point to llvm-symbolizer:

ASAN_SYMBOLIZER_PATH=$(which llvm-symbolizer) ./program

Practical Example: Detecting Use-After-Free

Create a file named example_UseAfterFree.cc:

int main() {
  int *arr = new int[10];
  delete[] arr;
  // Trigger use-after-free
  return arr[5];
}

Compile and run:

clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc -o uaf
ASAN_SYMBOLIZER_PATH=$(which llvm-symbolizer) ./uaf

ASan outputs a detailed error report:


==1234==ERROR: AddressSanitizer heap-use-after-free on address 0x6020000000a0 ...
    #0 0x40123a in main example_UseAfterFree.cc:5
    #1 0x7f... in __libc_start_main ...

Summary

  • LLVM sanitizers are defined in clang/include/clang/Basic/Sanitizers.def and activated via -fsanitize= flags.
  • AddressSanitizer detects memory corruption bugs by instrumenting code in llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp.
  • Enable ASan by compiling with -fsanitize=address and ensuring your Clang build includes the compiler-rt runtime.
  • Use ASAN_OPTIONS and ASAN_SYMBOLIZER_PATH to configure runtime behavior and stack trace symbolization.

Frequently Asked Questions

What is the difference between AddressSanitizer and MemorySanitizer?

AddressSanitizer detects memory addressability issues like use-after-free and buffer overflows, while MemorySanitizer (-fsanitize=memory) detects reads of uninitialized memory. They use different instrumentation passes and runtime libraries, though both reside in compiler-rt.

Can I use AddressSanitizer in kernel space?

Yes. The KernelAddressSanitizer (KASan) is available via -fsanitize=kernel-address and is designed for kernel-mode code. It uses different runtime hooks than user-space ASan and requires specific kernel configuration options.

Why does my program abort immediately after the first ASan error?

This is by design. AddressSanitizer calls __asan::Abort() after printing the error report to prevent further corruption. You can disable this behavior for testing purposes by setting halt_on_error=0 in ASAN_OPTIONS, though continuing after memory corruption is generally unsafe.

How do I integrate AddressSanitizer into a CMake build?

Use the helper module in runtimes/cmake/Modules/GetSanitizerFlags.cmake or manually append -fsanitize=address to your CMAKE_CXX_FLAGS and CMAKE_C_FLAGS. Ensure you link against the compiler-rt runtime by verifying that LLVM_ENABLE_RUNTIMES includes compiler-rt in your toolchain build.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →