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