403 lines · plain
1================2AddressSanitizer3================4 5.. contents::6 :local:7 8Introduction9============10 11AddressSanitizer is a fast memory error detector. It consists of a compiler12instrumentation module and a run-time library. The tool can detect the13following types of bugs:14 15* Out-of-bounds accesses to heap, stack and globals16* Use-after-free17* 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 free22* Memory leaks (experimental)23 24Typical slowdown introduced by AddressSanitizer is **2x**.25 26How to build27============28 29Build LLVM/Clang with `CMake <https://llvm.org/docs/CMake.html>`_ and enable30the ``compiler-rt`` runtime. An example CMake configuration that will allow31for the use/testing of AddressSanitizer:32 33.. code-block:: console34 35 $ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_ENABLE_RUNTIMES="compiler-rt" <path to source>/llvm36 37Usage38=====39 40Simply compile and link your program with ``-fsanitize=address`` flag. The41AddressSanitizer run-time library should be linked to the final executable, so42make sure to use ``clang`` (not ``ld``) for the final link step. When linking43shared libraries, the AddressSanitizer run-time is not linked, so44``-Wl,-z,defs`` may cause link errors (don't use it with AddressSanitizer). To45get a reasonable performance add ``-O1`` or higher. To get nicer stack traces46in error messages add ``-fno-omit-frame-pointer``. To get perfect stack traces47you may need to disable inlining (just use ``-O1``) and tail call elimination48(``-fno-optimize-sibling-calls``).49 50.. code-block:: console51 52 % cat example_UseAfterFree.cc53 int main(int argc, char **argv) {54 int *array = new int[100];55 delete [] array;56 return array[argc]; // BOOM57 }58 59 # Compile and link60 % clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc61 62or:63 64.. code-block:: console65 66 # Compile67 % clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer -c example_UseAfterFree.cc68 # Link69 % clang++ -g -fsanitize=address example_UseAfterFree.o70 71If a bug is detected, the program will print an error message to stderr and72exit 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 code76 (both by ~5%).77* Fixing bugs becomes unavoidable. AddressSanitizer does not produce78 false alarms. Once a memory corruption occurs, the program is in an inconsistent79 state, which could lead to confusing results and potentially misleading80 subsequent reports.81 82If your process is sandboxed and you are running on OS X 10.10 or earlier, you83will need to set ``DYLD_INSERT_LIBRARIES`` environment variable and point it to84the ASan library that is packaged with the compiler used to build the85executable. (You can find the library by searching for dynamic libraries with86``asan`` in their name.) If the environment variable is not set, the process will87try 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 Reports91=========================92 93To make AddressSanitizer symbolize its output94you need to set the ``ASAN_SYMBOLIZER_PATH`` environment variable to point to95the ``llvm-symbolizer`` binary (or make sure ``llvm-symbolizer`` is in your96``$PATH``):97 98.. code-block:: console99 100 % ASAN_SYMBOLIZER_PATH=/usr/local/bin/llvm-symbolizer ./a.out101 ==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8102 READ of size 4 at 0x7f7ddab8c084 thread T0103 #0 0x403c8c in main example_UseAfterFree.cc:4104 #1 0x7f7ddabcac4d in __libc_start_main ??:0105 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*) ??:0108 #1 0x403c53 in main example_UseAfterFree.cc:4109 #2 0x7f7ddabcac4d in __libc_start_main ??:0110 previously allocated by thread T0 here:111 #0 0x404544 in operator new[](unsigned long) ??:0112 #1 0x403c43 in main example_UseAfterFree.cc:2113 #2 0x7f7ddabcac4d in __libc_start_main ??:0114 ==9442== ABORTING115 116If that does not work for you (e.g. your process is sandboxed), you can use a117separate script to symbolize the result offline (online symbolization can be118force disabled by setting ``ASAN_OPTIONS=symbolize=0``):119 120.. code-block:: console121 122 % ASAN_OPTIONS=symbolize=0 ./a.out 2> log123 % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt124 ==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8125 READ of size 4 at 0x7f7ddab8c084 thread T0126 #0 0x403c8c in main example_UseAfterFree.cc:4127 #1 0x7f7ddabcac4d in __libc_start_main ??:0128 ...129 130Note that on macOS you may need to run ``dsymutil`` on your binary to have the131file\:line info in the AddressSanitizer reports.132 133Additional Checks134=================135 136Initialization order checking137-----------------------------138 139AddressSanitizer can optionally detect dynamic initialization order problems,140when initialization of globals defined in one translation unit uses141globals defined in another translation unit. To enable this check at runtime,142you should set environment variable143``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 explicitly152(``-fsanitize-address-use-after-return=runtime``).153To disable this check at runtime, set the environment variable154``ASAN_OPTIONS=detect_stack_use_after_return=0``.155 156Enabling this check (``-fsanitize-address-use-after-return=always``) will157reduce code size. The code size may be reduced further by completely158eliminating 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 disabled via the163 runtime environment (``ASAN_OPTIONS=detect_stack_use_after_return=0``).164 * ``always``: Enables detection of UAR errors in all cases. (reduces code165 size, but not as much as ``never``).166 167Container Overflow Detection168----------------------------169 170AddressSanitizer can detect overflows in containers with custom allocators171(such as std::vector) where the library developers have added calls into the172AddressSanitizer runtime to indicate which memory is poisoned etc.173 174In environments where not all the process binaries can be recompiled with 175AddressSanitizer enabled, these checks can cause false positives.176 177See `Disabling container overflow checks`_ for details on suppressing checks.178 179Memory leak detection180---------------------181 182For more information on leak detector in AddressSanitizer, see183:doc:`LeakSanitizer`. The leak detection is turned on by default on Linux,184and can be enabled using ``ASAN_OPTIONS=detect_leaks=1`` on macOS;185however, it is not yet supported on other platforms.186 187Issue Suppression188=================189 190AddressSanitizer is not expected to produce false positives. If you see one,191look again; most likely it is a true positive!192 193Suppressing Reports in External Libraries194-----------------------------------------195Runtime interposition allows AddressSanitizer to find bugs in code that is196not being recompiled. If you run into an issue in external libraries, we197recommend immediately reporting it to the library maintainer so that it198gets addressed. However, you can use the following suppression mechanism199to unblock yourself and continue on with the testing. This suppression200mechanism should only be used for suppressing issues in external code; it201does not work on code recompiled with AddressSanitizer. To suppress errors202in external libraries, set the ``ASAN_OPTIONS`` environment variable to point203to a suppression file. You can either specify the full path to the file or the204path of the file relative to the location of your executable.205 206.. code-block:: bash207 208 ASAN_OPTIONS=suppressions=MyASan.supp209 210Use the following format to specify the names of the functions or libraries211you want to suppress. You can see these in the error report. Remember that212the narrower the scope of the suppression, the more bugs you will be able to213catch.214 215.. code-block:: bash216 217 interceptor_via_fun:NameOfCFunctionToSuppress218 interceptor_via_fun:-[ClassName objCMethodToSuppress:]219 interceptor_via_lib:NameOfTheLibraryToSuppress220 221Conditional Compilation with ``__has_feature(address_sanitizer)``222-----------------------------------------------------------------223 224In some cases one may need to execute different code depending on whether225AddressSanitizer is enabled.226:ref:`\_\_has\_feature <langext-__has_feature-__has_extension>` can be used for227this purpose.228 229.. code-block:: c230 231 #if defined(__has_feature)232 # if __has_feature(address_sanitizer)233 // code that builds only under AddressSanitizer234 # endif235 #endif236 237Disabling Instrumentation with ``__attribute__((no_sanitize("address")))``238--------------------------------------------------------------------------239 240Some code should not be instrumented by AddressSanitizer. One may use241the attribute ``__attribute__((no_sanitize("address")))`` (which has242deprecated synonyms `no_sanitize_address` and243`no_address_safety_analysis`) to disable instrumentation of a244particular function. This attribute may not be supported by other245compilers, so we suggest to use it together with246``__has_feature(address_sanitizer)``.247 248The same attribute used on a global variable prevents AddressSanitizer249from adding redzones around it and detecting out of bounds accesses.250 251 252AddressSanitizer also supports253``__attribute__((disable_sanitizer_instrumentation))``. This attribute254works similarly to ``__attribute__((no_sanitize("address")))``, but it also255prevents instrumentation performed by other sanitizers.256 257Disabling container overflow checks258-----------------------------------259 260Runtime suppression261^^^^^^^^^^^^^^^^^^^262 263Container overflow checks can be disabled at runtime using the264``ASAN_OPTIONS=detect_container_overflow=0`` environment variable.265 266Compile time suppression267^^^^^^^^^^^^^^^^^^^^^^^^268 269``-D__SANITIZER_DISABLE_CONTAINER_OVERFLOW__`` can be used at compile time to270disable container overflow checks if the container library has added support271for this define.272 273To support a standard way to disable container overflow checks at compile time,274library developers should use this definition in conjunction with the 275AddressSanitizer feature test to conditionally include container overflow 276related code compiled into user code:277 278The recommended form is279 280.. code-block:: c281 282 // include the sanitizer common interfaces283 #include <sanitizer/common_interface_defs.h>284 285 #if __has_feature(address_sanitizer)286 // Container overflow detection enabled - include annotations287 __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid);288 #endif289 290This pattern ensures that:291 292* Container overflow annotations are only included when AddressSanitizer is293 enabled294* Container overflow detection can be disabled by passing 295 ``-D__SANITIZER_DISABLE_CONTAINER_OVERFLOW__`` to the compiler296 297Suppressing Errors in Recompiled Code (Ignorelist)298--------------------------------------------------299 300AddressSanitizer supports ``src`` and ``fun`` entity types in301:doc:`SanitizerSpecialCaseList`, that can be used to suppress error reports302in the specified source files or functions. Additionally, AddressSanitizer303introduces ``global`` and ``type`` entity types that can be used to304suppress error reports for out-of-bound access to globals with certain305names and types (you may only specify class or struct types).306 307You may use an ``init`` category to suppress reports about initialization-order308problems happening in certain source files or with certain global variables.309 310.. code-block:: bash311 312 # Suppress error reports for code in a file or in a function:313 src:bad_file.cpp314 # Ignore all functions with names containing MyFooBar:315 fun:*MyFooBar*316 # Disable out-of-bound checks for global:317 global:bad_array318 # Disable out-of-bound checks for global instances of a given class ...319 type:Namespace::BadClassName320 # ... or a given struct. Use wildcard to deal with anonymous namespace.321 type:Namespace2::*::BadStructName322 # Disable initialization-order checks for globals:323 global:bad_init_global=init324 type:*BadInitClassSubstring*=init325 src:bad/init/files/*=init326 327Suppressing memory leaks328------------------------329 330Memory leak reports produced by :doc:`LeakSanitizer` (if it is run as a part331of AddressSanitizer) can be suppressed by a separate file passed as332 333.. code-block:: bash334 335 LSAN_OPTIONS=suppressions=MyLSan.supp336 337which contains lines of the form `leak:<pattern>`. Memory leak will be338suppressed if pattern matches any function name, source file name, or339library name in the symbolized stack trace of the leak report. See340`full documentation341<https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#suppressions>`_342for more details.343 344Code generation control345=======================346 347Instrumentation code outlining348------------------------------349 350By default AddressSanitizer inlines the instrumentation code to improve the351run-time performance, which leads to increased binary size. Using the352(clang flag ``-fsanitize-address-outline-instrumentation`` default: ``false``)353flag forces all code instrumentation to be outlined, which reduces the size354of the generated code, but also reduces the run-time performance.355 356Limitations357===========358 359* AddressSanitizer uses more real memory than a native run. Exact overhead360 depends on the allocation sizes. The smaller the allocations you make the361 bigger the overhead is.362* AddressSanitizer uses more stack memory. We have seen up to 3x increase.363* On 64-bit platforms AddressSanitizer maps (but not reserves) 16+ Terabytes of364 virtual address space. This means that tools like ``ulimit`` may not work as365 usually expected.366* Static linking of executables is not supported.367 368Security Considerations369=======================370 371AddressSanitizer is a bug detection tool and its runtime is not meant to be372linked against production executables. While it may be useful for testing,373AddressSanitizer's runtime was not developed with security-sensitive374constraints in mind and may compromise the security of the resulting executable.375 376Supported Platforms377===================378 379AddressSanitizer is supported on:380 381* Linux382* macOS383* iOS Simulator384* Android385* NetBSD386* FreeBSD387* Windows 8.1+388 389Current Status390==============391 392AddressSanitizer is fully functional on supported platforms starting from LLVM3933.1. The test suite is integrated into CMake build and can be run with ``make394check-asan`` command.395 396The Windows port is functional and is used by Chrome and Firefox, but it is not397as well supported as the other ports.398 399More Information400================401 402`<https://github.com/google/sanitizers/wiki/AddressSanitizer>`_403