1================ 2AddressSanitizer 3================ 4 5.. contents:: 6 :local: 7 8Introduction 9============ 10 11AddressSanitizer is a fast memory error detector. It consists of a compiler 12instrumentation module and a run-time library. The tool can detect the 13following types of bugs: 14 15* Out-of-bounds accesses to heap, stack and globals 16* Use-after-free 17* Use-after-return (to some extent) 18* Double-free, invalid free 19* Memory leaks (experimental) 20 21Typical slowdown introduced by AddressSanitizer is **2x**. 22 23How to build 24============ 25 26Build LLVM/Clang with `CMake <http://llvm.org/docs/CMake.html>`_. 27 28Usage 29===== 30 31Simply compile and link your program with ``-fsanitize=address`` flag. The 32AddressSanitizer run-time library should be linked to the final executable, so 33make sure to use ``clang`` (not ``ld``) for the final link step. When linking 34shared libraries, the AddressSanitizer run-time is not linked, so 35``-Wl,-z,defs`` may cause link errors (don't use it with AddressSanitizer). To 36get a reasonable performance add ``-O1`` or higher. To get nicer stack traces 37in error messages add ``-fno-omit-frame-pointer``. To get perfect stack traces 38you may need to disable inlining (just use ``-O1``) and tail call elimination 39(``-fno-optimize-sibling-calls``). 40 41.. code-block:: console 42 43 % cat example_UseAfterFree.cc 44 int main(int argc, char **argv) { 45 int *array = new int[100]; 46 delete [] array; 47 return array[argc]; // BOOM 48 } 49 50 # Compile and link 51 % clang -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc 52 53or: 54 55.. code-block:: console 56 57 # Compile 58 % clang -O1 -g -fsanitize=address -fno-omit-frame-pointer -c example_UseAfterFree.cc 59 # Link 60 % clang -g -fsanitize=address example_UseAfterFree.o 61 62If a bug is detected, the program will print an error message to stderr and 63exit with a non-zero exit code. To make AddressSanitizer symbolize its output 64you need to set the ``ASAN_SYMBOLIZER_PATH`` environment variable to point to 65the ``llvm-symbolizer`` binary (or make sure ``llvm-symbolizer`` is in your 66``$PATH``): 67 68.. code-block:: console 69 70 % ASAN_SYMBOLIZER_PATH=/usr/local/bin/llvm-symbolizer ./a.out 71 ==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8 72 READ of size 4 at 0x7f7ddab8c084 thread T0 73 #0 0x403c8c in main example_UseAfterFree.cc:4 74 #1 0x7f7ddabcac4d in __libc_start_main ??:0 75 0x7f7ddab8c084 is located 4 bytes inside of 400-byte region [0x7f7ddab8c080,0x7f7ddab8c210) 76 freed by thread T0 here: 77 #0 0x404704 in operator delete[](void*) ??:0 78 #1 0x403c53 in main example_UseAfterFree.cc:4 79 #2 0x7f7ddabcac4d in __libc_start_main ??:0 80 previously allocated by thread T0 here: 81 #0 0x404544 in operator new[](unsigned long) ??:0 82 #1 0x403c43 in main example_UseAfterFree.cc:2 83 #2 0x7f7ddabcac4d in __libc_start_main ??:0 84 ==9442== ABORTING 85 86If that does not work for you (e.g. your process is sandboxed), you can use a 87separate script to symbolize the result offline (online symbolization can be 88force disabled by setting ``ASAN_OPTIONS=symbolize=0``): 89 90.. code-block:: console 91 92 % ASAN_OPTIONS=symbolize=0 ./a.out 2> log 93 % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt 94 ==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8 95 READ of size 4 at 0x7f7ddab8c084 thread T0 96 #0 0x403c8c in main example_UseAfterFree.cc:4 97 #1 0x7f7ddabcac4d in __libc_start_main ??:0 98 ... 99 100Note that on OS X you may need to run ``dsymutil`` on your binary to have the 101file\:line info in the AddressSanitizer reports. 102 103AddressSanitizer exits on the first detected error. This is by design. 104One reason: it makes the generated code smaller and faster (both by 105~5%). Another reason: this makes fixing bugs unavoidable. With Valgrind, 106it is often the case that users treat Valgrind warnings as false 107positives (which they are not) and don't fix them. 108 109``__has_feature(address_sanitizer)`` 110------------------------------------ 111 112In some cases one may need to execute different code depending on whether 113AddressSanitizer is enabled. 114:ref:`\_\_has\_feature <langext-__has_feature-__has_extension>` can be used for 115this purpose. 116 117.. code-block:: c 118 119 #if defined(__has_feature) 120 # if __has_feature(address_sanitizer) 121 // code that builds only under AddressSanitizer 122 # endif 123 #endif 124 125``__attribute__((no_sanitize_address))`` 126----------------------------------------------- 127 128Some code should not be instrumented by AddressSanitizer. One may use the 129function attribute 130:ref:`no_sanitize_address <langext-address_sanitizer>` 131(or a deprecated synonym `no_address_safety_analysis`) 132to disable instrumentation of a particular function. This attribute may not be 133supported by other compilers, so we suggest to use it together with 134``__has_feature(address_sanitizer)``. 135 136Initialization order checking 137----------------------------- 138 139AddressSanitizer can optionally detect dynamic initialization order problems, 140when initialization of globals defined in one translation unit uses 141globals defined in another translation unit. To enable this check at runtime, 142you should set environment variable 143``ASAN_OPTIONS=check_initialization_order=1``. 144 145Blacklist 146--------- 147 148AddressSanitizer supports ``src`` and ``fun`` entity types in 149:doc:`SanitizerSpecialCaseList`, that can be used to suppress error reports 150in the specified source files or functions. Additionally, AddressSanitizer 151introduces ``global`` and ``type`` entity types that can be used to 152suppress error reports for out-of-bound access to globals with certain 153names and types (you may only specify class or struct types). 154 155You may use an ``init`` category to suppress reports about initialization-order 156problems happening in certain source files or with certain global variables. 157 158.. code-block:: bash 159 160 # Suppress error reports for code in a file or in a function: 161 src:bad_file.cpp 162 # Ignore all functions with names containing MyFooBar: 163 fun:*MyFooBar* 164 # Disable out-of-bound checks for global: 165 global:bad_array 166 # Disable out-of-bound checks for global instances of a given class ... 167 type:Namespace::BadClassName 168 # ... or a given struct. Use wildcard to deal with anonymous namespace. 169 type:Namespace2::*::BadStructName 170 # Disable initialization-order checks for globals: 171 global:bad_init_global=init 172 type:*BadInitClassSubstring*=init 173 src:bad/init/files/*=init 174 175Memory leak detection 176--------------------- 177 178For the experimental memory leak detector in AddressSanitizer, see 179:doc:`LeakSanitizer`. 180 181Supported Platforms 182=================== 183 184AddressSanitizer is supported on 185 186* Linux i386/x86\_64 (tested on Ubuntu 12.04); 187* MacOS 10.6 - 10.9 (i386/x86\_64). 188* Android ARM 189* FreeBSD i386/x86\_64 (tested on FreeBSD 11-current) 190 191Ports to various other platforms are in progress. 192 193Limitations 194=========== 195 196* AddressSanitizer uses more real memory than a native run. Exact overhead 197 depends on the allocations sizes. The smaller the allocations you make the 198 bigger the overhead is. 199* AddressSanitizer uses more stack memory. We have seen up to 3x increase. 200* On 64-bit platforms AddressSanitizer maps (but not reserves) 16+ Terabytes of 201 virtual address space. This means that tools like ``ulimit`` may not work as 202 usually expected. 203* Static linking is not supported. 204 205Current Status 206============== 207 208AddressSanitizer is fully functional on supported platforms starting from LLVM 2093.1. The test suite is integrated into CMake build and can be run with ``make 210check-asan`` command. 211 212More Information 213================ 214 215`http://code.google.com/p/address-sanitizer <http://code.google.com/p/address-sanitizer/>`_ 216 217