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