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