|  | ================ | 
|  | 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 | 
|  | * Memory leaks (experimental) | 
|  |  | 
|  | 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. To make AddressSanitizer symbolize its output | 
|  | you need to set the ``ASAN_SYMBOLIZER_PATH`` environment variable to point to | 
|  | the ``llvm-symbolizer`` binary (or make sure ``llvm-symbolizer`` is in your | 
|  | ``$PATH``): | 
|  |  | 
|  | .. code-block:: console | 
|  |  | 
|  | % ASAN_SYMBOLIZER_PATH=/usr/local/bin/llvm-symbolizer ./a.out | 
|  | ==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 | 
|  |  | 
|  | If that does not work for you (e.g. your process is sandboxed), you can use a | 
|  | separate script to symbolize the result offline (online symbolization can be | 
|  | force disabled by setting ``ASAN_OPTIONS=symbolize=0``): | 
|  |  | 
|  | .. code-block:: console | 
|  |  | 
|  | % ASAN_OPTIONS=symbolize=0 ./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 | 
|  | ... | 
|  |  | 
|  | Note that on OS X you may need to run ``dsymutil`` on your binary to have the | 
|  | file\:line info in the AddressSanitizer reports. | 
|  |  | 
|  | 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 <langext-__has_feature-__has_extension>` 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_sanitize_address))`` | 
|  | ----------------------------------------------- | 
|  |  | 
|  | Some code should not be instrumented by AddressSanitizer. One may use the | 
|  | function attribute | 
|  | :ref:`no_sanitize_address <langext-address_sanitizer>` | 
|  | (or a deprecated synonym `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)``. | 
|  |  | 
|  | Initialization order checking | 
|  | ----------------------------- | 
|  |  | 
|  | AddressSanitizer can optionally detect dynamic initialization order problems, | 
|  | when initialization of globals defined in one translation unit uses | 
|  | globals defined in another translation unit. To enable this check at runtime, | 
|  | you should set environment variable | 
|  | ``ASAN_OPTIONS=check_initialization_order=1``. | 
|  |  | 
|  | Blacklist | 
|  | --------- | 
|  |  | 
|  | AddressSanitizer supports ``src`` and ``fun`` entity types in | 
|  | :doc:`SanitizerSpecialCaseList`, that can be used to suppress error reports | 
|  | in the specified source files or functions. Additionally, AddressSanitizer | 
|  | introduces ``global`` and ``type`` entity types that can be used to | 
|  | suppress error reports for out-of-bound access to globals with certain | 
|  | names and types (you may only specify class or struct types). | 
|  |  | 
|  | You may use an ``init`` category to suppress reports about initialization-order | 
|  | problems happening in certain source files or with certain global variables. | 
|  |  | 
|  | .. code-block:: bash | 
|  |  | 
|  | # Suppress error reports for code in a file or in a function: | 
|  | src:bad_file.cpp | 
|  | # Ignore all functions with names containing MyFooBar: | 
|  | fun:*MyFooBar* | 
|  | # Disable out-of-bound checks for global: | 
|  | global:bad_array | 
|  | # Disable out-of-bound checks for global instances of a given class ... | 
|  | type:Namespace::BadClassName | 
|  | # ... or a given struct. Use wildcard to deal with anonymous namespace. | 
|  | type:Namespace2::*::BadStructName | 
|  | # Disable initialization-order checks for globals: | 
|  | global:bad_init_global=init | 
|  | type:*BadInitClassSubstring*=init | 
|  | src:bad/init/files/*=init | 
|  |  | 
|  | Memory leak detection | 
|  | --------------------- | 
|  |  | 
|  | For the experimental memory leak detector in AddressSanitizer, see | 
|  | :doc:`LeakSanitizer`. | 
|  |  | 
|  | Supported Platforms | 
|  | =================== | 
|  |  | 
|  | AddressSanitizer is supported on | 
|  |  | 
|  | * Linux i386/x86\_64 (tested on Ubuntu 12.04); | 
|  | * MacOS 10.6 - 10.9 (i386/x86\_64). | 
|  | * Android ARM | 
|  | * FreeBSD i386/x86\_64 (tested on FreeBSD 11-current) | 
|  |  | 
|  | Ports to various other platforms are in progress. | 
|  |  | 
|  | 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 <http://code.google.com/p/address-sanitizer/>`_ | 
|  |  |