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
     60     WARNING: MemorySanitizer: use-of-uninitialized-value
     61         #0 0x7f45944b418a in main umr.cc:6
     62         #1 0x7f45938b676c in __libc_start_main libc-start.c:226
     63 
     64 By default, MemorySanitizer exits on the first detected error.
     65 
     66 ``__has_feature(memory_sanitizer)``
     67 ------------------------------------
     68 
     69 In some cases one may need to execute different code depending on
     70 whether MemorySanitizer is enabled. :ref:`\_\_has\_feature
     71 <langext-__has_feature-__has_extension>` can be used for this purpose.
     72 
     73 .. code-block:: c
     74 
     75     #if defined(__has_feature)
     76     #  if __has_feature(memory_sanitizer)
     77     // code that builds only under MemorySanitizer
     78     #  endif
     79     #endif
     80 
     81 ``__attribute__((no_sanitize_memory))``
     82 -----------------------------------------------
     83 
     84 Some code should not be checked by MemorySanitizer.
     85 One may use the function attribute
     86 :ref:`no_sanitize_memory <langext-memory_sanitizer>`
     87 to disable uninitialized checks in a particular function.
     88 MemorySanitizer may still instrument such functions to avoid false positives.
     89 This attribute may not be
     90 supported by other compilers, so we suggest to use it together with
     91 ``__has_feature(memory_sanitizer)``.
     92 
     93 Blacklist
     94 ---------
     95 
     96 MemorySanitizer supports ``src`` and ``fun`` entity types in
     97 :doc:`SanitizerSpecialCaseList`, that can be used to relax MemorySanitizer
     98 checks for certain source files and functions. All "Use of uninitialized value"
     99 warnings will be suppressed and all values loaded from memory will be
    100 considered fully initialized.
    101 
    102 Report symbolization
    103 ====================
    104 
    105 MemorySanitizer uses an external symbolizer to print files and line numbers in
    106 reports. Make sure that ``llvm-symbolizer`` binary is in ``PATH``,
    107 or set environment variable ``MSAN_SYMBOLIZER_PATH`` to point to it.
    108 
    109 Origin Tracking
    110 ===============
    111 
    112 MemorySanitizer can track origins of unitialized values, similar to
    113 Valgrind's --track-origins option. This feature is enabled by
    114 ``-fsanitize-memory-track-origins`` Clang option. With the code from
    115 the example above,
    116 
    117 .. code-block:: console
    118 
    119     % clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -g -O2 umr.cc
    120     % ./a.out
    121     WARNING: MemorySanitizer: use-of-uninitialized-value
    122         #0 0x7f7893912f0b in main umr2.cc:6
    123         #1 0x7f789249b76c in __libc_start_main libc-start.c:226
    124 
    125       Uninitialized value was created by a heap allocation
    126         #0 0x7f7893901cbd in operator new[](unsigned long) msan_new_delete.cc:44
    127         #1 0x7f7893912e06 in main umr2.cc:4
    128 
    129 Origin tracking has proved to be very useful for debugging MemorySanitizer
    130 reports. It slows down program execution by a factor of 1.5x-2x on top
    131 of the usual MemorySanitizer slowdown.
    132 
    133 MemorySanitizer can provide even more information with
    134 ``-fsanitize-memory-track-origins=2`` flag. In this mode reports
    135 include information about intermediate stores the uninitialized value went
    136 through.
    137 
    138 .. code-block:: console
    139 
    140     % cat umr2.cc
    141     #include <stdio.h>
    142 
    143     int main(int argc, char** argv) {
    144       int* a = new int[10];
    145       a[5] = 0;
    146       volatile int b = a[argc];
    147       if (b)
    148         printf("xx\n");
    149       return 0;
    150     }
    151 
    152     % clang -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O2 umr2.cc
    153     % ./a.out
    154     WARNING: MemorySanitizer: use-of-uninitialized-value
    155         #0 0x7f7893912f0b in main umr2.cc:7
    156         #1 0x7f789249b76c in __libc_start_main libc-start.c:226
    157 
    158       Uninitialized value was stored to memory at
    159         #0 0x7f78938b5c25 in __msan_chain_origin msan.cc:484
    160         #1 0x7f7893912ecd in main umr2.cc:6
    161 
    162       Uninitialized value was created by a heap allocation
    163         #0 0x7f7893901cbd in operator new[](unsigned long) msan_new_delete.cc:44
    164         #1 0x7f7893912e06 in main umr2.cc:4
    165 
    166 
    167 Handling external code
    168 ============================
    169 
    170 MemorySanitizer requires that all program code is instrumented. This
    171 also includes any libraries that the program depends on, even libc.
    172 Failing to achieve this may result in false reports.
    173 
    174 Full MemorySanitizer instrumentation is very difficult to achieve. To
    175 make it easier, MemorySanitizer runtime library includes 70+
    176 interceptors for the most common libc functions. They make it possible
    177 to run MemorySanitizer-instrumented programs linked with
    178 uninstrumented libc. For example, the authors were able to bootstrap
    179 MemorySanitizer-instrumented Clang compiler by linking it with
    180 self-built instrumented libcxx (as a replacement for libstdc++).
    181 
    182 In the case when rebuilding all program dependencies with
    183 MemorySanitizer is problematic, an experimental MSanDR tool can be
    184 used. It is a DynamoRio-based tool that uses dynamic instrumentation
    185 to avoid false positives due to uninstrumented code. The tool simply
    186 marks memory from instrumented libraries as fully initialized. See
    187 `http://code.google.com/p/memory-sanitizer/wiki/Running#Running_with_the_dynamic_tool`
    188 for more information.
    189 
    190 Supported Platforms
    191 ===================
    192 
    193 MemorySanitizer is supported on
    194 
    195 * Linux x86\_64 (tested on Ubuntu 12.04);
    196 
    197 Limitations
    198 ===========
    199 
    200 * MemorySanitizer uses 2x more real memory than a native run, 3x with
    201   origin tracking.
    202 * MemorySanitizer maps (but not reserves) 64 Terabytes of virtual
    203   address space. This means that tools like ``ulimit`` may not work as
    204   usually expected.
    205 * Static linking is not supported.
    206 * Non-position-independent executables are not supported.  Therefore, the
    207   ``fsanitize=memory`` flag will cause Clang to act as though the ``-fPIE``
    208   flag had been supplied if compiling without ``-fPIC``, and as though the
    209   ``-pie`` flag had been supplied if linking an executable.
    210 * Depending on the version of Linux kernel, running without ASLR may
    211   be not supported. Note that GDB disables ASLR by default. To debug
    212   instrumented programs, use "set disable-randomization off".
    213 
    214 Current Status
    215 ==============
    216 
    217 MemorySanitizer is an experimental tool. It is known to work on large
    218 real-world programs, like Clang/LLVM itself.
    219 
    220 More Information
    221 ================
    222 
    223 `http://code.google.com/p/memory-sanitizer <http://code.google.com/p/memory-sanitizer/>`_
    224 
    225