AddressSanitizer
Introduction
AddressSanitizer is a fast memory error detector. It consists of a compiler instrumentation module and a run-time library. The tool can detect the following types of bugs:- Out-of-bounds accesses to heap, stack and globals
- Use-after-free
- Use-after-return (to some extent)
- Double-free, invalid free
How to build
Follow the clang build instructions.Note: CMake build does not work yet. See bug 12272.
Usage
Simply compile and link your program with -faddress-sanitizer flag.To get a reasonable performance add -O1 or higher.
To get nicer stack traces in error messages add -fno-omit-frame-pointer.
To get perfect stack traces you may need to disable inlining (just use -O1) and tail call elimination (-fno-optimize-sibling-calls).
% cat example_UseAfterFree.cc int main(int argc, char **argv) { int *array = new int[100]; delete [] array; return array[argc]; // BOOM }
% clang -O1 -g -faddress-sanitizer -fno-omit-frame-pointer example_UseAfterFree.ccIf a bug is detected, the program will print an error message to stderr and exit with a non-zero exit code. Currently, AddressSanitizer does not symbolize its output, so you may need to use a separate script to symbolize the result offline (this will be fixed in future).
% ./a.out 2> log % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt ==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8 READ of size 4 at 0x7f7ddab8c084 thread T0 #0 0x403c8c in main example_UseAfterFree.cc:4 #1 0x7f7ddabcac4d in __libc_start_main ??:0 0x7f7ddab8c084 is located 4 bytes inside of 400-byte region [0x7f7ddab8c080,0x7f7ddab8c210) freed by thread T0 here: #0 0x404704 in operator delete[](void*) ??:0 #1 0x403c53 in main example_UseAfterFree.cc:4 #2 0x7f7ddabcac4d in __libc_start_main ??:0 previously allocated by thread T0 here: #0 0x404544 in operator new[](unsigned long) ??:0 #1 0x403c43 in main example_UseAfterFree.cc:2 #2 0x7f7ddabcac4d in __libc_start_main ??:0 ==9442== ABORTING
__has_feature(address_sanitizer)
In some cases one may need to execute different code depending on whether AddressSanitizer is enabled. __has_feature can be used for this purpose.#if defined(__has_feature) # if __has_feature(address_sanitizer) code that builds only under AddressSanitizer # endif #endif
__attribute__((no_address_safety_analysis))
Some code should not be instrumentated by AddressSanitizer. One may use the function attribute no_address_safety_analysis to disable instrumentation of a particular function. This attribute may not be supported by other compilers, so we suggest to use it together with __has_feature(address_sanitizer). Note: currently, this attribute will be lost if the function is inlined.Supported Platforms
AddressSanitizer is supported on- Linux x86_64 (tested on Ubuntu 10.04).
- MacOS 10.6 and 10.7 (i386/x86_64).
Limitations
- AddressSanitizer uses more real memory than a native run. How much -- depends on the allocations sizes. The smaller the allocations you make the bigger the overhead.
- AddressSanitizer uses more stack memory. We have seen up to 3x increase.
- On 64-bit platforms AddressSanitizer maps (but not reserves) 16+ Terabytes of virtual address space. This means that tools like ulimit may not work as usually expected.
- Static linking is not supported.