Address Sanitization (ASan)
Address Sanitization - as performed by a tool such as AddressSanitizer (ASan) - is a method for runtime memory error detection. It tries to detect invalid memory accesses, such as the ones caused by out-of-bounds array indices or use-after-free. It is a compiler feature in clang (LLVM) and GCC.
It can be enabled with the compiler flag -fsanitize=address
. To get nicer stack
traces in error messages add -fno-omit-frame-pointer
.
Its scope of error detection includes:
- Use-after-free (dangling pointer dereference)
- Heap buffer overflow
- Stack buffer overflow
- Global buffer overflow
- Use-after-return
- Use-after-scope
- Initialization order bugs
- Memory leaks
Integrating ASan
ASan supports user-set poisoned memory addresses. To use
asan_poison_memory_region(addr, size)
only when compiling with enabled ASan, use
the following preprocessor code:
#if defined(_MSC_VER) #if defined(__SANITIZE_ADDRESS__) #define ASAN_ENABLED 1 #define NO_ASAN __declspec(no_sanitize_address) #else #define NO_ASAN #endif #elif defined(__clang__) #if defined(__has_feature) #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) #define ASAN_ENABLED 1 #endif #endif #define NO_ASAN __attribute__((no_sanitize("address"))) #else #warning "NO_ASAN is not defined for this compiler." #endif #if defined(__cplusplus) #define C_LINKAGE extern "C" #else #define C_LINKAGE #endif #if ASAN_ENABLED #if defined(_WIN32) #pragma comment(lib, "clang_rt.asan-x86_64.lib") #endif C_LINKAGE void __asan_poison_memory_region(void const volatile *addr, size_t size); C_LINKAGE void __asan_unpoison_memory_region(void const volatile *addr, size_t size); #define asan_poison_memory_region(addr, size) __asan_poison_memory_region((addr), (size)) #define asan_unpoison_memory_region(addr, size) __asan_unpoison_memory_region((addr), (size)) #else #define asan_poison_memory_region(addr, size) ((void)(addr), (void)(size)) #define asan_unpoison_memory_region(addr, size) ((void)(addr), (void)(size)) #endif