Home | History | Annotate | Download | only in docs
      1 ================
      2 MemorySanitizer
      3 ================
      4 
      5 .. contents::
      6    :local:
      7 
      8 Introduction
      9 ============
     10 
     11 MemorySanitizer is a detector of uninitialized reads. It consists of a
     12 compiler instrumentation module and a run-time library.
     13 
     14 Typical slowdown introduced by MemorySanitizer is **3x**.
     15 
     16 How to build
     17 ============
     18 
     19 Follow the `clang build instructions <../get_started.html>`_. CMake
     20 build is supported.
     21 
     22 Usage
     23 =====
     24 
     25 Simply compile and link your program with ``-fsanitize=memory`` flag.
     26 The MemorySanitizer run-time library should be linked to the final
     27 executable, so make sure to use ``clang`` (not ``ld``) for the final
     28 link step. When linking shared libraries, the MemorySanitizer run-time
     29 is not linked, so ``-Wl,-z,defs`` may cause link errors (don't use it
     30 with MemorySanitizer). To get a reasonable performance add ``-O1`` or
     31 higher. To get meaninful stack traces in error messages add
     32 ``-fno-omit-frame-pointer``. To get perfect stack traces you may need
     33 to disable inlining (just use ``-O1``) and tail call elimination
     34 (``-fno-optimize-sibling-calls``).
     35 
     36 .. code-block:: console
     37 
     38     % cat umr.cc
     39     #include <stdio.h>
     40 
     41     int main(int argc, char** argv) {
     42       int* a = new int[10];
     43       a[5] = 0;
     44       if (a[argc])
     45         printf("xx\n");
     46       return 0;
     47     }
     48 
     49     % clang -fsanitize=memory -fno-omit-frame-pointer -g -O2 umr.cc
     50 
     51 If a bug is detected, the program will print an error message to
     52 stderr and exit with a non-zero exit code. Currently, MemorySanitizer
     53 does not symbolize its output by default, so you may need to use a
     54 separate script to symbolize the result offline (this will be fixed in
     55 future).
     56 
     57 .. code-block:: console
     58 
     59     % ./a.out 2>log
     60     % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt
     61     ==30106==  WARNING: MemorySanitizer: UMR (uninitialized-memory-read)
     62         #0 0x7f45944b418a in main umr.cc:6
     63         #1 0x7f45938b676c in __libc_start_main libc-start.c:226
     64     Exiting
     65 
     66 By default, MemorySanitizer exits on the first detected error.
     67 
     68 ``__has_feature(memory_sanitizer)``
     69 ------------------------------------
     70 
     71 In some cases one may need to execute different code depending on
     72 whether MemorySanitizer is enabled. :ref:`\_\_has\_feature
     73 <langext-__has_feature-__has_extension>` can be used for this purpose.
     74 
     75 .. code-block:: c
     76 
     77     #if defined(__has_feature)
     78     #  if __has_feature(memory_sanitizer)
     79     // code that builds only under MemorySanitizer
     80     #  endif
     81     #endif
     82 
     83 ``__attribute__((no_sanitize_memory))``
     84 -----------------------------------------------
     85 
     86 Some code should not be checked by MemorySanitizer.
     87 One may use the function attribute
     88 :ref:`no_sanitize_memory <langext-memory_sanitizer>`
     89 to disable uninitialized checks in a particular function.
     90 MemorySanitizer may still instrument such functions to avoid false positives.
     91 This attribute may not be
     92 supported by other compilers, so we suggest to use it together with
     93 ``__has_feature(memory_sanitizer)``. Note: currently, this attribute will be
     94 lost if the function is inlined.
     95 
     96 Blacklist
     97 ---------
     98 
     99 MemorySanitizer supports ``src`` and ``fun`` entity types in
    100 :doc:`SanitizerSpecialCaseList`, that can be used to relax MemorySanitizer
    101 checks for certain source files and functions. All "Use of uninitialized value"
    102 warnings will be suppressed and all values loaded from memory will be
    103 considered fully initialized.
    104 
    105 Origin Tracking
    106 ===============
    107 
    108 MemorySanitizer can track origins of unitialized values, similar to
    109 Valgrind's --track-origins option. This feature is enabled by
    110 ``-fsanitize-memory-track-origins`` Clang option. With the code from
    111 the example above,
    112 
    113 .. code-block:: console
    114 
    115     % clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -g -O2 umr.cc
    116     % ./a.out 2>log
    117     % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt
    118     ==14425==  WARNING: MemorySanitizer: UMR (uninitialized-memory-read)
    119     ==14425== WARNING: Trying to symbolize code, but external symbolizer is not initialized!
    120         #0 0x7f8bdda3824b in main umr.cc:6
    121         #1 0x7f8bdce3a76c in __libc_start_main libc-start.c:226
    122       raw origin id: 2030043137
    123       ORIGIN: heap allocation:
    124         #0 0x7f8bdda4034b in operator new[](unsigned long) msan_new_delete.cc:39
    125         #1 0x7f8bdda3814d in main umr.cc:4
    126         #2 0x7f8bdce3a76c in __libc_start_main libc-start.c:226
    127     Exiting
    128 
    129 Origin tracking has proved to be very useful for debugging UMR
    130 reports. It slows down program execution by a factor of 1.5x-2x on top
    131 of the usual MemorySanitizer slowdown.
    132 
    133 Handling external code
    134 ============================
    135 
    136 MemorySanitizer requires that all program code is instrumented. This
    137 also includes any libraries that the program depends on, even libc.
    138 Failing to achieve this may result in false UMR reports.
    139 
    140 Full MemorySanitizer instrumentation is very difficult to achieve. To
    141 make it easier, MemorySanitizer runtime library includes 70+
    142 interceptors for the most common libc functions. They make it possible
    143 to run MemorySanitizer-instrumented programs linked with
    144 uninstrumented libc. For example, the authors were able to bootstrap
    145 MemorySanitizer-instrumented Clang compiler by linking it with
    146 self-built instrumented libcxx (as a replacement for libstdc++).
    147 
    148 In the case when rebuilding all program dependencies with
    149 MemorySanitizer is problematic, an experimental MSanDR tool can be
    150 used. It is a DynamoRio-based tool that uses dynamic instrumentation
    151 to avoid false positives due to uninstrumented code. The tool simply
    152 marks memory from instrumented libraries as fully initialized. See
    153 `http://code.google.com/p/memory-sanitizer/wiki/Running#Running_with_the_dynamic_tool`
    154 for more information.
    155 
    156 Supported Platforms
    157 ===================
    158 
    159 MemorySanitizer is supported on
    160 
    161 * Linux x86\_64 (tested on Ubuntu 10.04 and 12.04);
    162 
    163 Limitations
    164 ===========
    165 
    166 * MemorySanitizer uses 2x more real memory than a native run, 3x with
    167   origin tracking.
    168 * MemorySanitizer maps (but not reserves) 64 Terabytes of virtual
    169   address space. This means that tools like ``ulimit`` may not work as
    170   usually expected.
    171 * Static linking is not supported.
    172 * Non-position-independent executables are not supported.  Therefore, the
    173   ``fsanitize=memory`` flag will cause Clang to act as though the ``-fPIE``
    174   flag had been supplied if compiling without ``-fPIC``, and as though the
    175   ``-pie`` flag had been supplied if linking an executable.
    176 * Depending on the version of Linux kernel, running without ASLR may
    177   be not supported. Note that GDB disables ASLR by default. To debug
    178   instrumented programs, use "set disable-randomization off".
    179 
    180 Current Status
    181 ==============
    182 
    183 MemorySanitizer is an experimental tool. It is known to work on large
    184 real-world programs, like Clang/LLVM itself.
    185 
    186 More Information
    187 ================
    188 
    189 `http://code.google.com/p/memory-sanitizer <http://code.google.com/p/memory-sanitizer/>`_
    190 
    191