================ AddressSanitizer ================ .. contents:: :local: 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 Typical slowdown introduced by AddressSanitizer is **2x**. How to build ============ Follow the `clang build instructions <../get_started.html>`_. CMake build is supported. Usage ===== Simply compile and link your program with ``-fsanitize=address`` flag. The AddressSanitizer run-time library should be linked to the final executable, so make sure to use ``clang`` (not ``ld``) for the final link step. When linking shared libraries, the AddressSanitizer run-time is not linked, so ``-Wl,-z,defs`` may cause link errors (don't use it with AddressSanitizer). 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``). .. code-block:: console % cat example_UseAfterFree.cc int main(int argc, char **argv) { int *array = new int[100]; delete [] array; return array[argc]; // BOOM } # Compile and link % clang -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc or: .. code-block:: console # Compile % clang -O1 -g -fsanitize=address -fno-omit-frame-pointer -c example_UseAfterFree.cc # Link % clang -g -fsanitize=address example_UseAfterFree.o If 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). .. code-block:: console % ./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 AddressSanitizer exits on the first detected error. This is by design. One reason: it makes the generated code smaller and faster (both by ~5%). Another reason: this makes fixing bugs unavoidable. With Valgrind, it is often the case that users treat Valgrind warnings as false positives (which they are not) and don't fix them. ``__has_feature(address_sanitizer)`` ------------------------------------ In some cases one may need to execute different code depending on whether AddressSanitizer is enabled. :ref:`\_\_has\_feature ` can be used for this purpose. .. code-block:: c #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 instrumented by AddressSanitizer. One may use the function attribute :ref:`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 i386/x86\_64 (tested on Ubuntu 10.04 and 12.04); * MacOS 10.6, 10.7 and 10.8 (i386/x86\_64). Support for Linux ARM (and Android ARM) is in progress (it may work, but is not guaranteed too). Limitations =========== * AddressSanitizer uses more real memory than a native run. Exact overhead depends on the allocations sizes. The smaller the allocations you make the bigger the overhead is. * 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. Current Status ============== AddressSanitizer is fully functional on supported platforms starting from LLVM 3.1. The test suite is integrated into CMake build and can be run with ``make check-asan`` command. More Information ================ `http://code.google.com/p/address-sanitizer `_