1*67e74705SXin Li================ 2*67e74705SXin LiMemorySanitizer 3*67e74705SXin Li================ 4*67e74705SXin Li 5*67e74705SXin Li.. contents:: 6*67e74705SXin Li :local: 7*67e74705SXin Li 8*67e74705SXin LiIntroduction 9*67e74705SXin Li============ 10*67e74705SXin Li 11*67e74705SXin LiMemorySanitizer is a detector of uninitialized reads. It consists of a 12*67e74705SXin Licompiler instrumentation module and a run-time library. 13*67e74705SXin Li 14*67e74705SXin LiTypical slowdown introduced by MemorySanitizer is **3x**. 15*67e74705SXin Li 16*67e74705SXin LiHow to build 17*67e74705SXin Li============ 18*67e74705SXin Li 19*67e74705SXin LiBuild LLVM/Clang with `CMake <http://llvm.org/docs/CMake.html>`_. 20*67e74705SXin Li 21*67e74705SXin LiUsage 22*67e74705SXin Li===== 23*67e74705SXin Li 24*67e74705SXin LiSimply compile and link your program with ``-fsanitize=memory`` flag. 25*67e74705SXin LiThe MemorySanitizer run-time library should be linked to the final 26*67e74705SXin Liexecutable, so make sure to use ``clang`` (not ``ld``) for the final 27*67e74705SXin Lilink step. When linking shared libraries, the MemorySanitizer run-time 28*67e74705SXin Liis not linked, so ``-Wl,-z,defs`` may cause link errors (don't use it 29*67e74705SXin Liwith MemorySanitizer). To get a reasonable performance add ``-O1`` or 30*67e74705SXin Lihigher. To get meaninful stack traces in error messages add 31*67e74705SXin Li``-fno-omit-frame-pointer``. To get perfect stack traces you may need 32*67e74705SXin Lito disable inlining (just use ``-O1``) and tail call elimination 33*67e74705SXin Li(``-fno-optimize-sibling-calls``). 34*67e74705SXin Li 35*67e74705SXin Li.. code-block:: console 36*67e74705SXin Li 37*67e74705SXin Li % cat umr.cc 38*67e74705SXin Li #include <stdio.h> 39*67e74705SXin Li 40*67e74705SXin Li int main(int argc, char** argv) { 41*67e74705SXin Li int* a = new int[10]; 42*67e74705SXin Li a[5] = 0; 43*67e74705SXin Li if (a[argc]) 44*67e74705SXin Li printf("xx\n"); 45*67e74705SXin Li return 0; 46*67e74705SXin Li } 47*67e74705SXin Li 48*67e74705SXin Li % clang -fsanitize=memory -fno-omit-frame-pointer -g -O2 umr.cc 49*67e74705SXin Li 50*67e74705SXin LiIf a bug is detected, the program will print an error message to 51*67e74705SXin Listderr and exit with a non-zero exit code. 52*67e74705SXin Li 53*67e74705SXin Li.. code-block:: console 54*67e74705SXin Li 55*67e74705SXin Li % ./a.out 56*67e74705SXin Li WARNING: MemorySanitizer: use-of-uninitialized-value 57*67e74705SXin Li #0 0x7f45944b418a in main umr.cc:6 58*67e74705SXin Li #1 0x7f45938b676c in __libc_start_main libc-start.c:226 59*67e74705SXin Li 60*67e74705SXin LiBy default, MemorySanitizer exits on the first detected error. If you 61*67e74705SXin Lifind the error report hard to understand, try enabling 62*67e74705SXin Li:ref:`origin tracking <msan-origins>`. 63*67e74705SXin Li 64*67e74705SXin Li``__has_feature(memory_sanitizer)`` 65*67e74705SXin Li------------------------------------ 66*67e74705SXin Li 67*67e74705SXin LiIn some cases one may need to execute different code depending on 68*67e74705SXin Liwhether MemorySanitizer is enabled. :ref:`\_\_has\_feature 69*67e74705SXin Li<langext-__has_feature-__has_extension>` can be used for this purpose. 70*67e74705SXin Li 71*67e74705SXin Li.. code-block:: c 72*67e74705SXin Li 73*67e74705SXin Li #if defined(__has_feature) 74*67e74705SXin Li # if __has_feature(memory_sanitizer) 75*67e74705SXin Li // code that builds only under MemorySanitizer 76*67e74705SXin Li # endif 77*67e74705SXin Li #endif 78*67e74705SXin Li 79*67e74705SXin Li``__attribute__((no_sanitize_memory))`` 80*67e74705SXin Li----------------------------------------------- 81*67e74705SXin Li 82*67e74705SXin LiSome code should not be checked by MemorySanitizer. One may use the function 83*67e74705SXin Liattribute `no_sanitize_memory` to disable uninitialized checks in a particular 84*67e74705SXin Lifunction. MemorySanitizer may still instrument such functions to avoid false 85*67e74705SXin Lipositives. This attribute may not be supported by other compilers, so we 86*67e74705SXin Lisuggest to use it together with ``__has_feature(memory_sanitizer)``. 87*67e74705SXin Li 88*67e74705SXin LiBlacklist 89*67e74705SXin Li--------- 90*67e74705SXin Li 91*67e74705SXin LiMemorySanitizer supports ``src`` and ``fun`` entity types in 92*67e74705SXin Li:doc:`SanitizerSpecialCaseList`, that can be used to relax MemorySanitizer 93*67e74705SXin Lichecks for certain source files and functions. All "Use of uninitialized value" 94*67e74705SXin Liwarnings will be suppressed and all values loaded from memory will be 95*67e74705SXin Liconsidered fully initialized. 96*67e74705SXin Li 97*67e74705SXin LiReport symbolization 98*67e74705SXin Li==================== 99*67e74705SXin Li 100*67e74705SXin LiMemorySanitizer uses an external symbolizer to print files and line numbers in 101*67e74705SXin Lireports. Make sure that ``llvm-symbolizer`` binary is in ``PATH``, 102*67e74705SXin Lior set environment variable ``MSAN_SYMBOLIZER_PATH`` to point to it. 103*67e74705SXin Li 104*67e74705SXin Li.. _msan-origins: 105*67e74705SXin Li 106*67e74705SXin LiOrigin Tracking 107*67e74705SXin Li=============== 108*67e74705SXin Li 109*67e74705SXin LiMemorySanitizer can track origins of uninitialized values, similar to 110*67e74705SXin LiValgrind's --track-origins option. This feature is enabled by 111*67e74705SXin Li``-fsanitize-memory-track-origins=2`` (or simply 112*67e74705SXin Li``-fsanitize-memory-track-origins``) Clang option. With the code from 113*67e74705SXin Lithe example above, 114*67e74705SXin Li 115*67e74705SXin Li.. code-block:: console 116*67e74705SXin Li 117*67e74705SXin Li % cat umr2.cc 118*67e74705SXin Li #include <stdio.h> 119*67e74705SXin Li 120*67e74705SXin Li int main(int argc, char** argv) { 121*67e74705SXin Li int* a = new int[10]; 122*67e74705SXin Li a[5] = 0; 123*67e74705SXin Li volatile int b = a[argc]; 124*67e74705SXin Li if (b) 125*67e74705SXin Li printf("xx\n"); 126*67e74705SXin Li return 0; 127*67e74705SXin Li } 128*67e74705SXin Li 129*67e74705SXin Li % clang -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O2 umr2.cc 130*67e74705SXin Li % ./a.out 131*67e74705SXin Li WARNING: MemorySanitizer: use-of-uninitialized-value 132*67e74705SXin Li #0 0x7f7893912f0b in main umr2.cc:7 133*67e74705SXin Li #1 0x7f789249b76c in __libc_start_main libc-start.c:226 134*67e74705SXin Li 135*67e74705SXin Li Uninitialized value was stored to memory at 136*67e74705SXin Li #0 0x7f78938b5c25 in __msan_chain_origin msan.cc:484 137*67e74705SXin Li #1 0x7f7893912ecd in main umr2.cc:6 138*67e74705SXin Li 139*67e74705SXin Li Uninitialized value was created by a heap allocation 140*67e74705SXin Li #0 0x7f7893901cbd in operator new[](unsigned long) msan_new_delete.cc:44 141*67e74705SXin Li #1 0x7f7893912e06 in main umr2.cc:4 142*67e74705SXin Li 143*67e74705SXin LiBy default, MemorySanitizer collects both allocation points and all 144*67e74705SXin Liintermediate stores the uninitialized value went through. Origin 145*67e74705SXin Litracking has proved to be very useful for debugging MemorySanitizer 146*67e74705SXin Lireports. It slows down program execution by a factor of 1.5x-2x on top 147*67e74705SXin Liof the usual MemorySanitizer slowdown and increases memory overhead. 148*67e74705SXin Li 149*67e74705SXin LiClang option ``-fsanitize-memory-track-origins=1`` enables a slightly 150*67e74705SXin Lifaster mode when MemorySanitizer collects only allocation points but 151*67e74705SXin Linot intermediate stores. 152*67e74705SXin Li 153*67e74705SXin LiUse-after-destruction detection 154*67e74705SXin Li=============================== 155*67e74705SXin Li 156*67e74705SXin LiYou can enable experimental use-after-destruction detection in MemorySanitizer. 157*67e74705SXin LiAfter invocation of the destructor, the object will be considered no longer 158*67e74705SXin Lireadable, and using underlying memory will lead to error reports in runtime. 159*67e74705SXin Li 160*67e74705SXin LiThis feature is still experimental, in order to enable it at runtime you need 161*67e74705SXin Lito: 162*67e74705SXin Li 163*67e74705SXin Li#. Pass addition Clang option ``-fsanitize-memory-use-after-dtor`` during 164*67e74705SXin Li compilation. 165*67e74705SXin Li#. Set environment variable `MSAN_OPTIONS=poison_in_dtor=1` before running 166*67e74705SXin Li the program. 167*67e74705SXin Li 168*67e74705SXin LiHandling external code 169*67e74705SXin Li====================== 170*67e74705SXin Li 171*67e74705SXin LiMemorySanitizer requires that all program code is instrumented. This 172*67e74705SXin Lialso includes any libraries that the program depends on, even libc. 173*67e74705SXin LiFailing to achieve this may result in false reports. 174*67e74705SXin LiFor the same reason you may need to replace all inline assembly code that writes to memory 175*67e74705SXin Liwith a pure C/C++ code. 176*67e74705SXin Li 177*67e74705SXin LiFull MemorySanitizer instrumentation is very difficult to achieve. To 178*67e74705SXin Limake it easier, MemorySanitizer runtime library includes 70+ 179*67e74705SXin Liinterceptors for the most common libc functions. They make it possible 180*67e74705SXin Lito run MemorySanitizer-instrumented programs linked with 181*67e74705SXin Liuninstrumented libc. For example, the authors were able to bootstrap 182*67e74705SXin LiMemorySanitizer-instrumented Clang compiler by linking it with 183*67e74705SXin Liself-built instrumented libc++ (as a replacement for libstdc++). 184*67e74705SXin Li 185*67e74705SXin LiSupported Platforms 186*67e74705SXin Li=================== 187*67e74705SXin Li 188*67e74705SXin LiMemorySanitizer is supported on Linux x86\_64/MIPS64/AArch64. 189*67e74705SXin Li 190*67e74705SXin LiLimitations 191*67e74705SXin Li=========== 192*67e74705SXin Li 193*67e74705SXin Li* MemorySanitizer uses 2x more real memory than a native run, 3x with 194*67e74705SXin Li origin tracking. 195*67e74705SXin Li* MemorySanitizer maps (but not reserves) 64 Terabytes of virtual 196*67e74705SXin Li address space. This means that tools like ``ulimit`` may not work as 197*67e74705SXin Li usually expected. 198*67e74705SXin Li* Static linking is not supported. 199*67e74705SXin Li* Older versions of MSan (LLVM 3.7 and older) didn't work with 200*67e74705SXin Li non-position-independent executables, and could fail on some Linux 201*67e74705SXin Li kernel versions with disabled ASLR. Refer to documentation for older versions 202*67e74705SXin Li for more details. 203*67e74705SXin Li 204*67e74705SXin LiCurrent Status 205*67e74705SXin Li============== 206*67e74705SXin Li 207*67e74705SXin LiMemorySanitizer is known to work on large real-world programs 208*67e74705SXin Li(like Clang/LLVM itself) that can be recompiled from source, including all 209*67e74705SXin Lidependent libraries. 210*67e74705SXin Li 211*67e74705SXin LiMore Information 212*67e74705SXin Li================ 213*67e74705SXin Li 214*67e74705SXin Li`<https://github.com/google/sanitizers/wiki/MemorySanitizer>`_ 215