This project is the home for Sanitizers: AddressSanitizer, MemorySanitizer, ThreadSanitizer, LeakSanitizer, and more The actual code resides in the LLVM repository. Here we keep extended documentation, bugs and some helper code.
The documentation for our tools:
AddressSanitizer (detects addressability issues) and LeakSanitizer (detects memory leaks)
ThreadSanitizer (detects data races and deadlocks) for C++ and Go
MemorySanitizer (detects use of uninitialized memory)
HWASAN, or Hardware-assisted AddressSanitizer, a newer variant of AddressSanitizer that consumes much less memory
UBSan, or UndefinedBehaviorSanitizer
Some of the sanitizers are also available for different OS Kernels:
KASAN
KMSAN
AddressSanitizer (aka ASan) is a memory error detector for C/C++. It finds:
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
This tool is very fast. The average slowdown of the instrumented program is ~2x (see AddressSanitizerPerformanceNumbers).
The run-time library replaces the malloc and free functions. The memory around malloc-ed regions (red zones) is poisoned. The free-ed memory is placed in quarantine and also poisoned. Every memory access in the program is transformed by the compiler in the following way:
Before:
*address = …; // or: … = *address;
After:
if (IsPoisoned(address)) {
ReportError(address, kAccessSize, kIsWrite);
}
*address = …; // or: … = *address;
The tricky part is how to implement IsPoisoned very fast and ReportError very compact. Also, instrumenting some of the accesses may be proven redundant.
https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm
In order to use AddressSanitizer you will need to compile and link your program using clang with the -fsanitize=address switch. To get a reasonable performance add -O1 or higher. To get nicer stack traces in error messages add -fno-omit-frame-pointer. Note: Clang 3.1 release uses another flag syntax.
-fsanitize=address -O1 -fno-omit-frame-pointer -g
The recommended way for GCC is to statically link against ASAN using -static-libasan. See the ldd output.
g++ -ggdb -fsanitize=address -fno-omit-frame-pointer -static-libstdc++ -static-libasan -lrt memory_leak.cpp
运行时:
ASAN_OPTIONS=help=1 ./a.out 可以列出所有支持的flag:
Available flags for AddressSanitizer:
quarantine_size
- Deprecated, please use quarantine_size_mb.
quarantine_size_mb
- Size (in Mb) of quarantine used to detect use-after-free errors. Lower value may reduce memory usage but increase the chance of false negatives.
redzone
- Minimal size (in bytes) of redzones around heap objects. Requirement: redzone >= 16, is a power of two.
max_redzone
- Maximal size (in bytes) of redzones around heap objects.
debug
- If set, prints some debugging information and does additional checks.
report_globals
- Controls the way to handle globals (0 - don't detect buffer overflow on globals, 1 - detect buffer overflow, 2 - print data about registered globals).
check_initialization_order
- If set, attempts to catch initialization order issues.
replace_str
- If set, uses custom wrappers and replacements for libc string functions to find more errors.
replace_intrin
- If set, uses custom wrappers for memset/memcpy/memmove intinsics.
mac_ignore_invalid_free
- Ignore invalid free() calls to work around some bugs. Used on OS X only.
detect_stack_use_after_return
- Enables stack-use-after-return checking at run-time.
min_uar_stack_size_log
- Minimum fake stack size log.
max_uar_stack_size_log
- Maximum fake stack size log.
uar_noreserve
- Use mmap with 'noreserve' flag to allocate fake stack.
max_malloc_fill_size
- ASan allocator flag. max_malloc_fill_size is the maximal amount of bytes that will be filled with malloc_fill_byte on malloc.
malloc_fill_byte
- Value used to fill the newly allocated memory.
allow_user_poisoning
- If set, user may manually mark memory regions as poisoned or unpoisoned.
sleep_before_dying
- Number of seconds to sleep between printing an error report and terminating the program. Useful for debugging purposes (e.g. when one needs to attach .
check_malloc_usable_size
- Allows the users to work around the bug in Nvidia drivers prior to 295.*.
unmap_shadow_on_exit
- If set, explicitly unmaps the (huge) shadow at exit.
protect_shadow_gap
- If set, mprotect the shadow gap
print_stats
- Print various statistics after printing an error message or if atexit=1.
print_legend
- Print the legend for the shadow bytes.
atexit
- If set, prints ASan exit stats even after program terminates successfully.
print_full_thread_history
- If set, prints thread creation stacks for the threads involved in the report and their ancestors up to the main thread.
poison_heap
- Poison (or not) the heap memory on [de]allocation. Zero value is useful for benchmarking the allocator or instrumentator.
poison_partial
- If true, poison partially addressable 8-byte aligned words (default=true). This flag affects heap and global buffers, but not stack buffers.
poison_array_cookie
- Poison (or not) the array cookie after operator new[].
alloc_dealloc_mismatch
- Report errors on malloc/delete, new/free, new/delete[], etc.
new_delete_type_mismatch
- Report errors on mismatch betwen size of new and delete.
strict_init_order
- If true, assume that dynamic initializers can never access globals from other modules, even if the latter are already initialized.
start_deactivated
- If true, ASan tweaks a bunch of other flags (quarantine, redzone, heap poisoning) to reduce memory consumption as much as possible, and restores them
detect_invalid_pointer_pairs
- If non-zero, try to detect operations like <, <=, >, >= and - on invalid pointer pairs (e.g. when pointers belong to different objects). The bigger th.
detect_container_overflow
- If true, honor the container overflow annotations. See https://code.google.com/p/address-sanitizer/wiki/ContainerOverflow
detect_odr_violation
- If >=2, detect violation of One-Definition-Rule (ODR); If ==1, detect ODR-violation only if the two variables have different sizes
dump_instruction_bytes
- If true, dump 16 bytes starting at the instruction that caused SEGV
suppressions
- Suppressions file name.
halt_on_error
- Crash the program after printing the first error report (WARNING: USE AT YOUR OWN RISK!)
symbolize
- If set, use the online symbolizer from common sanitizer runtime to turn virtual addresses to file/line locations.
external_symbolizer_path
- Path to external symbolizer. If empty, the tool will search $PATH for the symbolizer.
allow_addr2line
- If set, allows online symbolizer to run addr2line binary to symbolize stack traces (addr2line will only be used if llvm-symbolizer binary is unavailab.
strip_path_prefix
- Strips this prefix from file paths in error reports.
fast_unwind_on_check
- If available, use the fast frame-pointer-based unwinder on internal CHECK failures.
fast_unwind_on_fatal
- If available, use the fast frame-pointer-based unwinder on fatal errors.
fast_unwind_on_malloc
- If available, use the fast frame-pointer-based unwinder on malloc/free.
handle_ioctl
- Intercept and handle ioctl requests.
malloc_context_size
- Max number of stack frames kept for each allocation/deallocation.
log_path
- Write logs to "log_path.pid". The special values are "stdout" and "stderr". The default is "stderr".
log_exe_name
- Mention name of executable when reporting error and append executable name to logs (as in "log_path.exe_name.pid").
log_to_syslog
- Write all sanitizer output to syslog in addition to other means of logging.
verbosity
- Verbosity level (0 - silent, 1 - a bit of output, 2+ - more output).
detect_leaks
- Enable memory leak detection.
leak_check_at_exit
- Invoke leak checking in an atexit handler. Has no effect if detect_leaks=false, or if __lsan_do_leak_check() is called before the handler has a chance.
allocator_may_return_null
- If false, the allocator will crash instead of returning 0 on out-of-memory.
print_summary
- If false, disable printing error summaries in addition to error reports.
check_printf
- Check printf arguments.
handle_segv
- If set, registers the tool's custom SIGSEGV/SIGBUS handler.
handle_abort
- If set, registers the tool's custom SIGABRT handler.
handle_sigfpe
- If set, registers the tool's custom SIGFPE handler.
allow_user_segv_handler
- If set, allows user to register a SEGV handler even if the tool registers one.
use_sigaltstack
- If set, uses alternate stack for signal handling.
detect_deadlocks
- If set, deadlock detection is enabled.
clear_shadow_mmap_threshold
- Large shadow regions are zero-filled using mmap(NORESERVE) instead of memset(). This is the threshold size in bytes.
color
- Colorize reports: (always|never|auto).
legacy_pthread_cond
- Enables support for dynamic libraries linked with libpthread 2.2.5.
intercept_tls_get_addr
- Intercept __tls_get_addr.
help
- Print the flag descriptions.
mmap_limit_mb
- Limit the amount of mmap-ed memory (excluding shadow) in Mb; not a user-facing flag, used mosly for testing the tools
hard_rss_limit_mb
- Hard RSS limit in Mb. If non-zero, a background thread is spawned at startup which periodically reads RSS and aborts the process if the limit is reachd
soft_rss_limit_mb
- Soft RSS limit in Mb. If non-zero, a background thread is spawned at startup which periodically reads RSS. If the limit is reached all subsequent mall.
can_use_proc_maps_statm
- If false, do not attempt to read /proc/maps/statm. Mostly useful for testing sanitizers.
coverage
- If set, coverage information will be dumped at program shutdown (if the coverage instrumentation was enabled at compile time).
coverage_pcs
- If set (and if 'coverage' is set too), the coverage information will be dumped as a set of PC offsets for every module.
coverage_order_pcs
- If true, the PCs will be dumped in the order they've appeared during the execution.
coverage_bitset
- If set (and if 'coverage' is set too), the coverage information will also be dumped as a bitset to a separate file.
coverage_counters
- If set (and if 'coverage' is set too), the bitmap that corresponds to coverage counters will be dumped.
coverage_direct
- If set, coverage information will be dumped directly to a memory mapped file. This way data is not lost even if the process is suddenly killed.
coverage_dir
- Target directory for coverage dumps. Defaults to the current directory.
full_address_space
- Sanitize complete address space; by default kernel area on 32-bit platforms will not be sanitized
print_suppressions
- Print matched suppressions at exit.
disable_coredump
- Disable core dumping. By default, disable_core=1 on 64-bit to avoid dumping a 16T+ core file. Ignored on OSes that don't dump core bydefault and for s.
use_madv_dontdump
- If set, instructs kernel to not store the (huge) shadow in core file.
symbolize_inline_frames
- Print inlined frames in stacktraces. Defaults to true.
symbolize_vs_style
- Print file locations in Visual Studio style (e.g: file(10,42): ...
stack_trace_format
- Format string used to render stack frames. See sanitizer_stacktrace_printer.h for the format description. Use DEFAULT to get default format.
no_huge_pages_for_shadow
- If true, the shadow is not allowed to use huge pages.
strict_string_checks
- If set check that string arguments are properly null-terminated
intercept_strstr
- If set, uses custom wrappers for strstr and strcasestr functions to find more errors.
intercept_strspn
- If set, uses custom wrappers for strspn and strcspn function to find more errors.
intercept_strpbrk
- If set, uses custom wrappers for strpbrk function to find more errors.
intercept_memcmp
- If set, uses custom wrappers for memcmp function to find more errors.
strict_memcmp
- If true, assume that memcmp(p1, p2, n) always reads n bytes before comparing p1 and p2.
decorate_proc_maps
- If set, decorate sanitizer mappings in /proc/self/maps with user-readable names
exitcode
- Override the program exit status if the tool found an error
abort_on_error
- If set, the tool calls abort() instead of _exit() after printing the error report.
include
- read more options from the given file
include_if_exists
- read more options from the given file (if it exists)
Q: Why didn’t ASan report an obviously invalid memory access in my code?
A1: If your errors is too obvious, compiler might have already optimized it out by the time Asan runs.
A2: Another, C-only option is accesses to global common symbols which are not protected by Asan (you can use -fno-common to disable generation of common symbols and hopefully detect more bugs).
A3: If _FORTIFY_SOURCE is enabled, ASan may have false positives, see next question.
Q: My malloc stacktraces are too short or do not make sense?
A: Try to compile your code with -fno-omit-frame-pointer or set ASAN_OPTIONS=fast_unwind_on_malloc=0 (the latter would be a performance killer though unless you also specify malloc_context_size=2 or lower). Note that frame-pointer-based unwinding does not work on Thumb.
Q: I’ve built my main executable with ASan. Do I also need to build shared libraries?
A: ASan will work even if you rebuild just part of your program. But you’ll have to rebuild all components to detect all errors.
Q: I’ve built my shared library with ASan. Can I run it with unsanitized executable?
A: Yes! You’ll need to build your library with dynamic version of ASan and then run executable with LD_PRELOAD=path/to/asan/runtime/lib.
Q: I’ve ran with ASAN_OPTIONS=verbosity=1 and ASan tells something like
30654 Parsed ASAN_OPTIONS: verbosity=1
30654 AddressSanitizer: failed to intercept ‘memcpy’
A: This warning is false (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58680 for details).
Q: On Linux I am seeings a crash at startup with something like this
ERROR: AddressSanitizer failed to allocate 0x400000000 (17179869184) bytes at address 67fff8000 (errno: 12)
A: Make sure you don’t have 2 in /proc/sys/vm/overcommit_memory
Q: Can I run AddressSanitizer with more aggressive diagnostics enabled?
A: Yes! In particular you may want to enable
CFLAGS += -fsanitize-address-use-after-scope
ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
check [Flags wiki] (https://github.com/google/sanitizers/wiki/AddressSanitizerFlags ) for more details on this.
参考资料:
https://github.com/google/sanitizers
https://github.com/google/sanitizers/wiki/AddressSanitizer
http://btorpey.github.io/blog/2014/03/27/using-clangs-address-sanitizer/
http://gavinchou.github.io/experience/summary/syntax/gcc-address-sanitizer/
https://lemire.me/blog/2019/05/16/building-better-software-with-better-tools-sanitizers-versus-valgrind/