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 (runtime flag `ASAN_OPTIONS=detect_stack_use_after_return=1`) 18* Use-after-scope (clang flag `-fsanitize-address-use-after-scope`) 19* Double-free, invalid free 20* Memory leaks (experimental) 21 22Typical slowdown introduced by AddressSanitizer is **2x**. 23 24How to build 25============ 26 27Build LLVM/Clang with `CMake <http://llvm.org/docs/CMake.html>`_. 28 29Usage 30===== 31 32Simply compile and link your program with ``-fsanitize=address`` flag. The 33AddressSanitizer run-time library should be linked to the final executable, so 34make sure to use ``clang`` (not ``ld``) for the final link step. When linking 35shared libraries, the AddressSanitizer run-time is not linked, so 36``-Wl,-z,defs`` may cause link errors (don't use it with AddressSanitizer). To 37get a reasonable performance add ``-O1`` or higher. To get nicer stack traces 38in error messages add ``-fno-omit-frame-pointer``. To get perfect stack traces 39you may need to disable inlining (just use ``-O1``) and tail call elimination 40(``-fno-optimize-sibling-calls``). 41 42.. code-block:: console 43 44 % cat example_UseAfterFree.cc 45 int main(int argc, char **argv) { 46 int *array = new int[100]; 47 delete [] array; 48 return array[argc]; // BOOM 49 } 50 51 # Compile and link 52 % clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc 53 54or: 55 56.. code-block:: console 57 58 # Compile 59 % clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer -c example_UseAfterFree.cc 60 # Link 61 % clang++ -g -fsanitize=address example_UseAfterFree.o 62 63If a bug is detected, the program will print an error message to stderr and 64exit with a non-zero exit code. AddressSanitizer exits on the first detected error. 65This is by design: 66 67* This approach allows AddressSanitizer to produce faster and smaller generated code 68 (both by ~5%). 69* Fixing bugs becomes unavoidable. AddressSanitizer does not produce 70 false alarms. Once a memory corruption occurs, the program is in an inconsistent 71 state, which could lead to confusing results and potentially misleading 72 subsequent reports. 73 74If your process is sandboxed and you are running on OS X 10.10 or earlier, you 75will need to set ``DYLD_INSERT_LIBRARIES`` environment variable and point it to 76the ASan library that is packaged with the compiler used to build the 77executable. (You can find the library by searching for dynamic libraries with 78``asan`` in their name.) If the environment variable is not set, the process will 79try to re-exec. Also keep in mind that when moving the executable to another machine, 80the ASan library will also need to be copied over. 81 82Symbolizing the Reports 83========================= 84 85To make AddressSanitizer symbolize its output 86you need to set the ``ASAN_SYMBOLIZER_PATH`` environment variable to point to 87the ``llvm-symbolizer`` binary (or make sure ``llvm-symbolizer`` is in your 88``$PATH``): 89 90.. code-block:: console 91 92 % ASAN_SYMBOLIZER_PATH=/usr/local/bin/llvm-symbolizer ./a.out 93 ==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8 94 READ of size 4 at 0x7f7ddab8c084 thread T0 95 #0 0x403c8c in main example_UseAfterFree.cc:4 96 #1 0x7f7ddabcac4d in __libc_start_main ??:0 97 0x7f7ddab8c084 is located 4 bytes inside of 400-byte region [0x7f7ddab8c080,0x7f7ddab8c210) 98 freed by thread T0 here: 99 #0 0x404704 in operator delete[](void*) ??:0 100 #1 0x403c53 in main example_UseAfterFree.cc:4 101 #2 0x7f7ddabcac4d in __libc_start_main ??:0 102 previously allocated by thread T0 here: 103 #0 0x404544 in operator new[](unsigned long) ??:0 104 #1 0x403c43 in main example_UseAfterFree.cc:2 105 #2 0x7f7ddabcac4d in __libc_start_main ??:0 106 ==9442== ABORTING 107 108If that does not work for you (e.g. your process is sandboxed), you can use a 109separate script to symbolize the result offline (online symbolization can be 110force disabled by setting ``ASAN_OPTIONS=symbolize=0``): 111 112.. code-block:: console 113 114 % ASAN_OPTIONS=symbolize=0 ./a.out 2> log 115 % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt 116 ==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8 117 READ of size 4 at 0x7f7ddab8c084 thread T0 118 #0 0x403c8c in main example_UseAfterFree.cc:4 119 #1 0x7f7ddabcac4d in __libc_start_main ??:0 120 ... 121 122Note that on OS X you may need to run ``dsymutil`` on your binary to have the 123file\:line info in the AddressSanitizer reports. 124 125Additional Checks 126================= 127 128Initialization order checking 129----------------------------- 130 131AddressSanitizer can optionally detect dynamic initialization order problems, 132when initialization of globals defined in one translation unit uses 133globals defined in another translation unit. To enable this check at runtime, 134you should set environment variable 135``ASAN_OPTIONS=check_initialization_order=1``. 136 137Note that this option is not supported on OS X. 138 139Memory leak detection 140--------------------- 141 142For more information on leak detector in AddressSanitizer, see 143:doc:`LeakSanitizer`. The leak detection is turned on by default on Linux, 144and can be enabled using ``ASAN_OPTIONS=detect_leaks=1`` on OS X; 145however, it is not yet supported on other platforms. 146 147Writable/Executable paging detection 148------------------------------------ 149 150The W^X detection is disabled by default and can be enabled using 151``ASAN_OPTIONS=detect_write_exec=1``. 152 153Issue Suppression 154================= 155 156AddressSanitizer is not expected to produce false positives. If you see one, 157look again; most likely it is a true positive! 158 159Suppressing Reports in External Libraries 160----------------------------------------- 161Runtime interposition allows AddressSanitizer to find bugs in code that is 162not being recompiled. If you run into an issue in external libraries, we 163recommend immediately reporting it to the library maintainer so that it 164gets addressed. However, you can use the following suppression mechanism 165to unblock yourself and continue on with the testing. This suppression 166mechanism should only be used for suppressing issues in external code; it 167does not work on code recompiled with AddressSanitizer. To suppress errors 168in external libraries, set the ``ASAN_OPTIONS`` environment variable to point 169to a suppression file. You can either specify the full path to the file or the 170path of the file relative to the location of your executable. 171 172.. code-block:: bash 173 174 ASAN_OPTIONS=suppressions=MyASan.supp 175 176Use the following format to specify the names of the functions or libraries 177you want to suppress. You can see these in the error report. Remember that 178the narrower the scope of the suppression, the more bugs you will be able to 179catch. 180 181.. code-block:: bash 182 183 interceptor_via_fun:NameOfCFunctionToSuppress 184 interceptor_via_fun:-[ClassName objCMethodToSuppress:] 185 interceptor_via_lib:NameOfTheLibraryToSuppress 186 187Conditional Compilation with ``__has_feature(address_sanitizer)`` 188----------------------------------------------------------------- 189 190In some cases one may need to execute different code depending on whether 191AddressSanitizer is enabled. 192:ref:`\_\_has\_feature <langext-__has_feature-__has_extension>` can be used for 193this purpose. 194 195.. code-block:: c 196 197 #if defined(__has_feature) 198 # if __has_feature(address_sanitizer) 199 // code that builds only under AddressSanitizer 200 # endif 201 #endif 202 203Disabling Instrumentation with ``__attribute__((no_sanitize("address")))`` 204-------------------------------------------------------------------------- 205 206Some code should not be instrumented by AddressSanitizer. One may use 207the attribute ``__attribute__((no_sanitize("address")))`` (which has 208deprecated synonyms `no_sanitize_address` and 209`no_address_safety_analysis`) to disable instrumentation of a 210particular function. This attribute may not be supported by other 211compilers, so we suggest to use it together with 212``__has_feature(address_sanitizer)``. 213 214The same attribute used on a global variable prevents AddressSanitizer 215from adding redzones around it and detecting out of bounds accesses. 216 217Suppressing Errors in Recompiled Code (Blacklist) 218------------------------------------------------- 219 220AddressSanitizer supports ``src`` and ``fun`` entity types in 221:doc:`SanitizerSpecialCaseList`, that can be used to suppress error reports 222in the specified source files or functions. Additionally, AddressSanitizer 223introduces ``global`` and ``type`` entity types that can be used to 224suppress error reports for out-of-bound access to globals with certain 225names and types (you may only specify class or struct types). 226 227You may use an ``init`` category to suppress reports about initialization-order 228problems happening in certain source files or with certain global variables. 229 230.. code-block:: bash 231 232 # Suppress error reports for code in a file or in a function: 233 src:bad_file.cpp 234 # Ignore all functions with names containing MyFooBar: 235 fun:*MyFooBar* 236 # Disable out-of-bound checks for global: 237 global:bad_array 238 # Disable out-of-bound checks for global instances of a given class ... 239 type:Namespace::BadClassName 240 # ... or a given struct. Use wildcard to deal with anonymous namespace. 241 type:Namespace2::*::BadStructName 242 # Disable initialization-order checks for globals: 243 global:bad_init_global=init 244 type:*BadInitClassSubstring*=init 245 src:bad/init/files/*=init 246 247Suppressing memory leaks 248------------------------ 249 250Memory leak reports produced by :doc:`LeakSanitizer` (if it is run as a part 251of AddressSanitizer) can be suppressed by a separate file passed as 252 253.. code-block:: bash 254 255 LSAN_OPTIONS=suppressions=MyLSan.supp 256 257which contains lines of the form `leak:<pattern>`. Memory leak will be 258suppressed if pattern matches any function name, source file name, or 259library name in the symbolized stack trace of the leak report. See 260`full documentation 261<https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#suppressions>`_ 262for more details. 263 264Limitations 265=========== 266 267* AddressSanitizer uses more real memory than a native run. Exact overhead 268 depends on the allocations sizes. The smaller the allocations you make the 269 bigger the overhead is. 270* AddressSanitizer uses more stack memory. We have seen up to 3x increase. 271* On 64-bit platforms AddressSanitizer maps (but not reserves) 16+ Terabytes of 272 virtual address space. This means that tools like ``ulimit`` may not work as 273 usually expected. 274* Static linking is not supported. 275 276Supported Platforms 277=================== 278 279AddressSanitizer is supported on: 280 281* Linux i386/x86\_64 (tested on Ubuntu 12.04) 282* OS X 10.7 - 10.11 (i386/x86\_64) 283* iOS Simulator 284* Android ARM 285* NetBSD i386/x86\_64 286* FreeBSD i386/x86\_64 (tested on FreeBSD 11-current) 287 288Ports to various other platforms are in progress. 289 290Current Status 291============== 292 293AddressSanitizer is fully functional on supported platforms starting from LLVM 2943.1. The test suite is integrated into CMake build and can be run with ``make 295check-asan`` command. 296 297More Information 298================ 299 300`<https://github.com/google/sanitizers/wiki/AddressSanitizer>`_ 301