Skip to main content

Sanitizers

The sanitizers module integrates compiler-based runtime error detectors into the build. These sanitizers instrument the compiled code to detect memory errors, data races, and undefined behavior at runtime — catching bugs that static analysis and testing alone cannot find.

The use of sanitizers in CI pipelines is mandated by ADR-0002 — C as the Core Language, which requires AddressSanitizer and UndefinedBehaviorSanitizer at minimum.

Available sanitizers

Four sanitizers are available, each controlled by a CMake cache option:

OptionSanitizerDetectsDefault
SANITIZE_ADDRESSAddressSanitizerBuffer overflows, use-after-free, stack overflowOFF
SANITIZE_MEMORYMemorySanitizerReads of uninitialized memory (Clang only)OFF
SANITIZE_THREADThreadSanitizerData races and deadlocksOFF
SANITIZE_UNDEFINEDUBSanUndefined behavior (integer overflow, null deref)OFF

Address, Memory, and Thread sanitizers are mutually exclusive — they cannot be combined because they use incompatible instrumentation strategies. Enabling more than one of these three produces a fatal configuration error. UndefinedBehaviorSanitizer can be combined freely with any of the others, and the standard presets generated by the scaffolding module pair it with AddressSanitizer in the asan preset.

When a sanitizer is enabled, the module verifies that the compiler and linker actually support it by running a test with check_linker_flag. If the sanitizer is not supported by the current toolchain, configuration fails with a clear error message.

For Address, Memory, and Thread sanitizers the module also adds -fno-omit-frame-pointer to ensure that runtime error reports include complete, readable stack traces. This flag is not needed for UndefinedBehaviorSanitizer, which reports errors inline at the point they occur.

Function reference

target_enable_sanitizers

target_enable_sanitizers(<target>)

Applies the configured sanitizer flags to a target as private compile and link options. When no sanitizers are enabled, this function is a no-op — targets can call it unconditionally.

add_library(mylib src/mylib.c)
target_enable_sanitizers(mylib)

add_executable(mylib-test tests/test.c)
target_enable_sanitizers(mylib-test)

Variables defined

VariableDescription
SANITIZER_COMPILE_OPTIONSCompiler flags for the enabled sanitizers
SANITIZER_LINK_OPTIONSLinker flags for the enabled sanitizers

Usage

The scaffolding module generates presets for each sanitizer combination:

make build PRESET=asan    # AddressSanitizer + UBSan
make build PRESET=tsan # ThreadSanitizer
make build PRESET=ubsan # UBSan only