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