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 <https://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 macOS 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 macOS. 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 macOS; 145however, it is not yet supported on other platforms. 146 147Issue Suppression 148================= 149 150AddressSanitizer is not expected to produce false positives. If you see one, 151look again; most likely it is a true positive! 152 153Suppressing Reports in External Libraries 154----------------------------------------- 155Runtime interposition allows AddressSanitizer to find bugs in code that is 156not being recompiled. If you run into an issue in external libraries, we 157recommend immediately reporting it to the library maintainer so that it 158gets addressed. However, you can use the following suppression mechanism 159to unblock yourself and continue on with the testing. This suppression 160mechanism should only be used for suppressing issues in external code; it 161does not work on code recompiled with AddressSanitizer. To suppress errors 162in external libraries, set the ``ASAN_OPTIONS`` environment variable to point 163to a suppression file. You can either specify the full path to the file or the 164path of the file relative to the location of your executable. 165 166.. code-block:: bash 167 168 ASAN_OPTIONS=suppressions=MyASan.supp 169 170Use the following format to specify the names of the functions or libraries 171you want to suppress. You can see these in the error report. Remember that 172the narrower the scope of the suppression, the more bugs you will be able to 173catch. 174 175.. code-block:: bash 176 177 interceptor_via_fun:NameOfCFunctionToSuppress 178 interceptor_via_fun:-[ClassName objCMethodToSuppress:] 179 interceptor_via_lib:NameOfTheLibraryToSuppress 180 181Conditional Compilation with ``__has_feature(address_sanitizer)`` 182----------------------------------------------------------------- 183 184In some cases one may need to execute different code depending on whether 185AddressSanitizer is enabled. 186:ref:`\_\_has\_feature <langext-__has_feature-__has_extension>` can be used for 187this purpose. 188 189.. code-block:: c 190 191 #if defined(__has_feature) 192 # if __has_feature(address_sanitizer) 193 // code that builds only under AddressSanitizer 194 # endif 195 #endif 196 197Disabling Instrumentation with ``__attribute__((no_sanitize("address")))`` 198-------------------------------------------------------------------------- 199 200Some code should not be instrumented by AddressSanitizer. One may use 201the attribute ``__attribute__((no_sanitize("address")))`` (which has 202deprecated synonyms `no_sanitize_address` and 203`no_address_safety_analysis`) to disable instrumentation of a 204particular function. This attribute may not be supported by other 205compilers, so we suggest to use it together with 206``__has_feature(address_sanitizer)``. 207 208The same attribute used on a global variable prevents AddressSanitizer 209from adding redzones around it and detecting out of bounds accesses. 210 211Suppressing Errors in Recompiled Code (Blacklist) 212------------------------------------------------- 213 214AddressSanitizer supports ``src`` and ``fun`` entity types in 215:doc:`SanitizerSpecialCaseList`, that can be used to suppress error reports 216in the specified source files or functions. Additionally, AddressSanitizer 217introduces ``global`` and ``type`` entity types that can be used to 218suppress error reports for out-of-bound access to globals with certain 219names and types (you may only specify class or struct types). 220 221You may use an ``init`` category to suppress reports about initialization-order 222problems happening in certain source files or with certain global variables. 223 224.. code-block:: bash 225 226 # Suppress error reports for code in a file or in a function: 227 src:bad_file.cpp 228 # Ignore all functions with names containing MyFooBar: 229 fun:*MyFooBar* 230 # Disable out-of-bound checks for global: 231 global:bad_array 232 # Disable out-of-bound checks for global instances of a given class ... 233 type:Namespace::BadClassName 234 # ... or a given struct. Use wildcard to deal with anonymous namespace. 235 type:Namespace2::*::BadStructName 236 # Disable initialization-order checks for globals: 237 global:bad_init_global=init 238 type:*BadInitClassSubstring*=init 239 src:bad/init/files/*=init 240 241Suppressing memory leaks 242------------------------ 243 244Memory leak reports produced by :doc:`LeakSanitizer` (if it is run as a part 245of AddressSanitizer) can be suppressed by a separate file passed as 246 247.. code-block:: bash 248 249 LSAN_OPTIONS=suppressions=MyLSan.supp 250 251which contains lines of the form `leak:<pattern>`. Memory leak will be 252suppressed if pattern matches any function name, source file name, or 253library name in the symbolized stack trace of the leak report. See 254`full documentation 255<https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#suppressions>`_ 256for more details. 257 258Limitations 259=========== 260 261* AddressSanitizer uses more real memory than a native run. Exact overhead 262 depends on the allocations sizes. The smaller the allocations you make the 263 bigger the overhead is. 264* AddressSanitizer uses more stack memory. We have seen up to 3x increase. 265* On 64-bit platforms AddressSanitizer maps (but not reserves) 16+ Terabytes of 266 virtual address space. This means that tools like ``ulimit`` may not work as 267 usually expected. 268* Static linking of executables is not supported. 269 270Supported Platforms 271=================== 272 273AddressSanitizer is supported on: 274 275* Linux i386/x86\_64 (tested on Ubuntu 12.04) 276* macOS 10.7 - 10.11 (i386/x86\_64) 277* iOS Simulator 278* Android ARM 279* NetBSD i386/x86\_64 280* FreeBSD i386/x86\_64 (tested on FreeBSD 11-current) 281* Windows 8.1+ (i386/x86\_64) 282 283Ports to various other platforms are in progress. 284 285Current Status 286============== 287 288AddressSanitizer is fully functional on supported platforms starting from LLVM 2893.1. The test suite is integrated into CMake build and can be run with ``make 290check-asan`` command. 291 292The Windows port is functional and is used by Chrome and Firefox, but it is not 293as well supported as the other ports. 294 295More Information 296================ 297 298`<https://github.com/google/sanitizers/wiki/AddressSanitizer>`_ 299