blob: 5bb19ed8a509128df0680399bd53f022339fd4f7 [file] [log] [blame]
Evgeniy Stepanov17d55902012-12-21 10:50:00 +00001================
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
Alexey Samsonov3a433f62015-02-18 22:26:20 +000019Build LLVM/Clang with `CMake <http://llvm.org/docs/CMake.html>`_.
Evgeniy Stepanov17d55902012-12-21 10:50:00 +000020
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
Sylvestre Ledru94a21042017-06-26 02:45:08 +000030higher. To get meaningful stack traces in error messages add
Evgeniy Stepanov17d55902012-12-21 10:50:00 +000031``-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
Dmitri Gribenko46735cb2012-12-23 18:36:44 +000036
Evgeniy Stepanov17d55902012-12-21 10:50:00 +000037 % 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
Peter Collingbourne54d770c2013-04-09 04:35:11 +000048 % clang -fsanitize=memory -fno-omit-frame-pointer -g -O2 umr.cc
Evgeniy Stepanov17d55902012-12-21 10:50:00 +000049
50If a bug is detected, the program will print an error message to
Alexey Samsonov1f7051e2015-12-04 22:50:44 +000051stderr and exit with a non-zero exit code.
Evgeniy Stepanov17d55902012-12-21 10:50:00 +000052
53.. code-block:: console
54
Evgeniy Stepanov2bfcaab2014-03-20 14:58:36 +000055 % ./a.out
56 WARNING: MemorySanitizer: use-of-uninitialized-value
Evgeniy Stepanov17d55902012-12-21 10:50:00 +000057 #0 0x7f45944b418a in main umr.cc:6
58 #1 0x7f45938b676c in __libc_start_main libc-start.c:226
Evgeniy Stepanov17d55902012-12-21 10:50:00 +000059
Alexey Samsonov1f7051e2015-12-04 22:50:44 +000060By 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>`.
Evgeniy Stepanov17d55902012-12-21 10:50:00 +000063
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
Anna Zaks80de16f2016-10-27 21:38:44 +000079``__attribute__((no_sanitize("memory")))``
Kostya Serebryany4c0fc992013-02-26 06:58:27 +000080-----------------------------------------------
81
Saleem Abdulrasool7f66d752015-10-19 01:24:08 +000082Some code should not be checked by MemorySanitizer. One may use the function
Anna Zaks80de16f2016-10-27 21:38:44 +000083attribute ``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)``.
Kostya Serebryany4c0fc992013-02-26 06:58:27 +000087
Alexey Samsonov2de68332013-08-07 08:23:32 +000088Blacklist
89---------
90
91MemorySanitizer supports ``src`` and ``fun`` entity types in
92:doc:`SanitizerSpecialCaseList`, that can be used to relax MemorySanitizer
93checks for certain source files and functions. All "Use of uninitialized value"
94warnings will be suppressed and all values loaded from memory will be
95considered fully initialized.
96
Evgeniy Stepanov2bfcaab2014-03-20 14:58:36 +000097Report symbolization
98====================
99
100MemorySanitizer uses an external symbolizer to print files and line numbers in
101reports. Make sure that ``llvm-symbolizer`` binary is in ``PATH``,
102or set environment variable ``MSAN_SYMBOLIZER_PATH`` to point to it.
103
Alexey Samsonov1f7051e2015-12-04 22:50:44 +0000104.. _msan-origins:
105
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000106Origin Tracking
107===============
108
Alexey Samsonov1f7051e2015-12-04 22:50:44 +0000109MemorySanitizer can track origins of uninitialized values, similar to
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000110Valgrind's --track-origins option. This feature is enabled by
Evgeniy Stepanov6e09bca2015-02-26 15:59:30 +0000111``-fsanitize-memory-track-origins=2`` (or simply
112``-fsanitize-memory-track-origins``) Clang option. With the code from
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000113the example above,
114
115.. code-block:: console
116
Evgeniy Stepanov2bfcaab2014-03-20 14:58:36 +0000117 % cat umr2.cc
118 #include <stdio.h>
119
120 int main(int argc, char** argv) {
121 int* a = new int[10];
122 a[5] = 0;
123 volatile int b = a[argc];
124 if (b)
125 printf("xx\n");
126 return 0;
127 }
128
129 % clang -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O2 umr2.cc
130 % ./a.out
131 WARNING: MemorySanitizer: use-of-uninitialized-value
132 #0 0x7f7893912f0b in main umr2.cc:7
133 #1 0x7f789249b76c in __libc_start_main libc-start.c:226
134
135 Uninitialized value was stored to memory at
136 #0 0x7f78938b5c25 in __msan_chain_origin msan.cc:484
137 #1 0x7f7893912ecd in main umr2.cc:6
138
139 Uninitialized value was created by a heap allocation
140 #0 0x7f7893901cbd in operator new[](unsigned long) msan_new_delete.cc:44
141 #1 0x7f7893912e06 in main umr2.cc:4
142
Evgeniy Stepanov6e09bca2015-02-26 15:59:30 +0000143By default, MemorySanitizer collects both allocation points and all
144intermediate stores the uninitialized value went through. Origin
145tracking has proved to be very useful for debugging MemorySanitizer
146reports. It slows down program execution by a factor of 1.5x-2x on top
Alexey Samsonov1f7051e2015-12-04 22:50:44 +0000147of the usual MemorySanitizer slowdown and increases memory overhead.
Evgeniy Stepanov6e09bca2015-02-26 15:59:30 +0000148
Alexey Samsonov1f7051e2015-12-04 22:50:44 +0000149Clang option ``-fsanitize-memory-track-origins=1`` enables a slightly
Evgeniy Stepanov6e09bca2015-02-26 15:59:30 +0000150faster mode when MemorySanitizer collects only allocation points but
151not intermediate stores.
Evgeniy Stepanov2bfcaab2014-03-20 14:58:36 +0000152
Alexey Samsonov1f7051e2015-12-04 22:50:44 +0000153Use-after-destruction detection
154===============================
155
156You can enable experimental use-after-destruction detection in MemorySanitizer.
157After invocation of the destructor, the object will be considered no longer
158readable, and using underlying memory will lead to error reports in runtime.
159
160This feature is still experimental, in order to enable it at runtime you need
161to:
162
163#. Pass addition Clang option ``-fsanitize-memory-use-after-dtor`` during
164 compilation.
165#. Set environment variable `MSAN_OPTIONS=poison_in_dtor=1` before running
166 the program.
167
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000168Handling external code
Alexey Samsonov1f7051e2015-12-04 22:50:44 +0000169======================
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000170
171MemorySanitizer requires that all program code is instrumented. This
172also includes any libraries that the program depends on, even libc.
Evgeniy Stepanov2bfcaab2014-03-20 14:58:36 +0000173Failing to achieve this may result in false reports.
Kostya Serebryany2494e8a2016-05-27 15:49:32 +0000174For the same reason you may need to replace all inline assembly code that writes to memory
175with a pure C/C++ code.
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000176
177Full MemorySanitizer instrumentation is very difficult to achieve. To
178make it easier, MemorySanitizer runtime library includes 70+
179interceptors for the most common libc functions. They make it possible
180to run MemorySanitizer-instrumented programs linked with
181uninstrumented libc. For example, the authors were able to bootstrap
182MemorySanitizer-instrumented Clang compiler by linking it with
Evgeniy Stepanov5e927b62015-01-26 09:17:37 +0000183self-built instrumented libc++ (as a replacement for libstdc++).
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000184
185Supported Platforms
186===================
187
Alexey Samsonov1f7051e2015-12-04 22:50:44 +0000188MemorySanitizer is supported on Linux x86\_64/MIPS64/AArch64.
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000189
190Limitations
191===========
192
193* MemorySanitizer uses 2x more real memory than a native run, 3x with
194 origin tracking.
195* MemorySanitizer maps (but not reserves) 64 Terabytes of virtual
196 address space. This means that tools like ``ulimit`` may not work as
197 usually expected.
198* Static linking is not supported.
Alexey Samsonov1f7051e2015-12-04 22:50:44 +0000199* Older versions of MSan (LLVM 3.7 and older) didn't work with
200 non-position-independent executables, and could fail on some Linux
201 kernel versions with disabled ASLR. Refer to documentation for older versions
202 for more details.
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000203
204Current Status
205==============
206
Alexey Samsonov1f7051e2015-12-04 22:50:44 +0000207MemorySanitizer is known to work on large real-world programs
208(like Clang/LLVM itself) that can be recompiled from source, including all
209dependent libraries.
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000210
211More Information
212================
213
Alexey Samsonov2e2469d2015-12-04 00:38:13 +0000214`<https://github.com/google/sanitizers/wiki/MemorySanitizer>`_