1================ 2MemorySanitizer 3================ 4 5.. contents:: 6 :local: 7 8Introduction 9============ 10 11MemorySanitizer is a detector of uninitialized reads. It consists of a 12compiler instrumentation module and a run-time library. 13 14Typical slowdown introduced by MemorySanitizer is **3x**. 15 16How to build 17============ 18 19Build LLVM/Clang with `CMake <https://llvm.org/docs/CMake.html>`_. 20 21Usage 22===== 23 24Simply compile and link your program with ``-fsanitize=memory`` flag. 25The MemorySanitizer run-time library should be linked to the final 26executable, so make sure to use ``clang`` (not ``ld``) for the final 27link step. When linking shared libraries, the MemorySanitizer run-time 28is not linked, so ``-Wl,-z,defs`` may cause link errors (don't use it 29with MemorySanitizer). To get a reasonable performance add ``-O1`` or 30higher. To get meaningful stack traces in error messages add 31``-fno-omit-frame-pointer``. To get perfect stack traces you may need 32to disable inlining (just use ``-O1``) and tail call elimination 33(``-fno-optimize-sibling-calls``). 34 35.. code-block:: console 36 37 % cat umr.cc 38 #include <stdio.h> 39 40 int main(int argc, char** argv) { 41 int* a = new int[10]; 42 a[5] = 0; 43 if (a[argc]) 44 printf("xx\n"); 45 return 0; 46 } 47 48 % clang -fsanitize=memory -fno-omit-frame-pointer -g -O2 umr.cc 49 50If a bug is detected, the program will print an error message to 51stderr and exit with a non-zero exit code. 52 53.. code-block:: console 54 55 % ./a.out 56 WARNING: MemorySanitizer: use-of-uninitialized-value 57 #0 0x7f45944b418a in main umr.cc:6 58 #1 0x7f45938b676c in __libc_start_main libc-start.c:226 59 60By default, MemorySanitizer exits on the first detected error. If you 61find the error report hard to understand, try enabling 62:ref:`origin tracking <msan-origins>`. 63 64``__has_feature(memory_sanitizer)`` 65------------------------------------ 66 67In some cases one may need to execute different code depending on 68whether MemorySanitizer is enabled. :ref:`\_\_has\_feature 69<langext-__has_feature-__has_extension>` can be used for this purpose. 70 71.. code-block:: c 72 73 #if defined(__has_feature) 74 # if __has_feature(memory_sanitizer) 75 // code that builds only under MemorySanitizer 76 # endif 77 #endif 78 79``__attribute__((no_sanitize("memory")))`` 80----------------------------------------------- 81 82Some code should not be checked by MemorySanitizer. One may use the function 83attribute ``no_sanitize("memory")`` to disable uninitialized checks in a 84particular function. MemorySanitizer may still instrument such functions to 85avoid false positives. This attribute may not be supported by other compilers, 86so we suggest to use it together with ``__has_feature(memory_sanitizer)``. 87 88``__attribute__((disable_sanitizer_instrumentation))`` 89-------------------------------------------------------- 90 91The ``disable_sanitizer_instrumentation`` attribute can be applied to functions 92to prevent all kinds of instrumentation. As a result, it may introduce false 93positives and therefore should be used with care, and only if absolutely 94required; for example for certain code that cannot tolerate any instrumentation 95and resulting side-effects. This attribute overrides ``no_sanitize("memory")``. 96 97Ignorelist 98---------- 99 100MemorySanitizer supports ``src`` and ``fun`` entity types in 101:doc:`SanitizerSpecialCaseList`, that can be used to relax MemorySanitizer 102checks for certain source files and functions. All "Use of uninitialized value" 103warnings will be suppressed and all values loaded from memory will be 104considered fully initialized. 105 106Report symbolization 107==================== 108 109MemorySanitizer uses an external symbolizer to print files and line numbers in 110reports. Make sure that ``llvm-symbolizer`` binary is in ``PATH``, 111or set environment variable ``MSAN_SYMBOLIZER_PATH`` to point to it. 112 113.. _msan-origins: 114 115Origin Tracking 116=============== 117 118MemorySanitizer can track origins of uninitialized values, similar to 119Valgrind's --track-origins option. This feature is enabled by 120``-fsanitize-memory-track-origins=2`` (or simply 121``-fsanitize-memory-track-origins``) Clang option. With the code from 122the example above, 123 124.. code-block:: console 125 126 % cat umr2.cc 127 #include <stdio.h> 128 129 int main(int argc, char** argv) { 130 int* a = new int[10]; 131 a[5] = 0; 132 volatile int b = a[argc]; 133 if (b) 134 printf("xx\n"); 135 return 0; 136 } 137 138 % clang -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O2 umr2.cc 139 % ./a.out 140 WARNING: MemorySanitizer: use-of-uninitialized-value 141 #0 0x7f7893912f0b in main umr2.cc:7 142 #1 0x7f789249b76c in __libc_start_main libc-start.c:226 143 144 Uninitialized value was stored to memory at 145 #0 0x7f78938b5c25 in __msan_chain_origin msan.cc:484 146 #1 0x7f7893912ecd in main umr2.cc:6 147 148 Uninitialized value was created by a heap allocation 149 #0 0x7f7893901cbd in operator new[](unsigned long) msan_new_delete.cc:44 150 #1 0x7f7893912e06 in main umr2.cc:4 151 152By default, MemorySanitizer collects both allocation points and all 153intermediate stores the uninitialized value went through. Origin 154tracking has proved to be very useful for debugging MemorySanitizer 155reports. It slows down program execution by a factor of 1.5x-2x on top 156of the usual MemorySanitizer slowdown and increases memory overhead. 157 158Clang option ``-fsanitize-memory-track-origins=1`` enables a slightly 159faster mode when MemorySanitizer collects only allocation points but 160not intermediate stores. 161 162Use-after-destruction detection 163=============================== 164 165MemorySanitizer includes use-after-destruction detection. After invocation of 166the destructor, the object will be considered no longer readable, and using 167underlying memory will lead to error reports in runtime. Refer to the standard 168for `lifetime <https://eel.is/c++draft/basic.life#1>`_ definition. 169 170This feature can be disabled with either: 171 172#. Pass addition Clang option ``-fno-sanitize-memory-use-after-dtor`` during 173 compilation. 174#. Set environment variable `MSAN_OPTIONS=poison_in_dtor=0` before running 175 the program. 176 177Handling external code 178====================== 179 180MemorySanitizer requires that all program code is instrumented. This 181also includes any libraries that the program depends on, even libc. 182Failing to achieve this may result in false reports. 183For the same reason you may need to replace all inline assembly code that writes to memory 184with a pure C/C++ code. 185 186Full MemorySanitizer instrumentation is very difficult to achieve. To 187make it easier, MemorySanitizer runtime library includes 70+ 188interceptors for the most common libc functions. They make it possible 189to run MemorySanitizer-instrumented programs linked with 190uninstrumented libc. For example, the authors were able to bootstrap 191MemorySanitizer-instrumented Clang compiler by linking it with 192self-built instrumented libc++ (as a replacement for libstdc++). 193 194Supported Platforms 195=================== 196 197MemorySanitizer is supported on the following OS: 198 199* Linux 200* NetBSD 201* FreeBSD 202 203Limitations 204=========== 205 206* MemorySanitizer uses 2x more real memory than a native run, 3x with 207 origin tracking. 208* MemorySanitizer maps (but not reserves) 64 Terabytes of virtual 209 address space. This means that tools like ``ulimit`` may not work as 210 usually expected. 211* Static linking is not supported. 212* Older versions of MSan (LLVM 3.7 and older) didn't work with 213 non-position-independent executables, and could fail on some Linux 214 kernel versions with disabled ASLR. Refer to documentation for older versions 215 for more details. 216* MemorySanitizer might be incompatible with position-independent executables 217 from FreeBSD 13 but there is a check done at runtime and throws a warning 218 in this case. 219 220Current Status 221============== 222 223MemorySanitizer is known to work on large real-world programs 224(like Clang/LLVM itself) that can be recompiled from source, including all 225dependent libraries. 226 227More Information 228================ 229 230`<https://github.com/google/sanitizers/wiki/MemorySanitizer>`_ 231