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

> Learn how to enable LLVM AddressSanitizer to detect memory errors like use-after-free and buffer overflows in your C++ code using the -fsanitize=address flag.

- Repository: [LLVM/llvm-project](https://github.com/llvm/llvm-project)
- Tags: how-to-guide
- Published: 2026-09-11

---

**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:

```bash
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`](https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp) and links the ASan runtime from `compiler-rt/lib/asan/`.

Use these flags for optimal results:

```bash
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:

```bash
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`:

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

```

## Practical Example: Detecting Use-After-Free

Create a file named `example_UseAfterFree.cc`:

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

```

Compile and run:

```bash
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`](https://github.com/llvm/llvm-project/blob/main/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.