blob: 9d6c22d8af085772f26715aa8dd34d1ef1ec74cc [file] [log] [blame]
Evgeniy Stepanovcc603e92012-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
19Follow the `clang build instructions <../get_started.html>`_. CMake
20build is supported.
21
22Usage
23=====
24
25Simply compile and link your program with ``-fsanitize=memory`` flag.
26The MemorySanitizer run-time library should be linked to the final
27executable, so make sure to use ``clang`` (not ``ld``) for the final
28link step. When linking shared libraries, the MemorySanitizer run-time
29is not linked, so ``-Wl,-z,defs`` may cause link errors (don't use it
30with MemorySanitizer). To get a reasonable performance add ``-O1`` or
31higher. To get meaninful stack traces in error messages add
32``-fno-omit-frame-pointer``. To get perfect stack traces you may need
33to disable inlining (just use ``-O1``) and tail call elimination
34(``-fno-optimize-sibling-calls``).
35
36.. code-block:: console
Dmitri Gribenko184e1c42012-12-23 18:36:44 +000037
Evgeniy Stepanovcc603e92012-12-21 10:50:00 +000038 % 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
Peter Collingbourne52ca70d2013-04-09 04:35:11 +000049 % clang -fsanitize=memory -fno-omit-frame-pointer -g -O2 umr.cc
Evgeniy Stepanovcc603e92012-12-21 10:50:00 +000050
51If a bug is detected, the program will print an error message to
52stderr and exit with a non-zero exit code. Currently, MemorySanitizer
53does not symbolize its output by default, so you may need to use a
54separate script to symbolize the result offline (this will be fixed in
55future).
56
57.. code-block:: console
58
Stephen Hines651f13c2014-04-23 16:59:28 -070059 % ./a.out
60 WARNING: MemorySanitizer: use-of-uninitialized-value
Evgeniy Stepanovcc603e92012-12-21 10:50:00 +000061 #0 0x7f45944b418a in main umr.cc:6
62 #1 0x7f45938b676c in __libc_start_main libc-start.c:226
Evgeniy Stepanovcc603e92012-12-21 10:50:00 +000063
64By default, MemorySanitizer exits on the first detected error.
65
66``__has_feature(memory_sanitizer)``
67------------------------------------
68
69In some cases one may need to execute different code depending on
70whether 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
Kostya Serebryany85aee962013-02-26 06:58:27 +000081``__attribute__((no_sanitize_memory))``
82-----------------------------------------------
83
84Some code should not be checked by MemorySanitizer.
85One may use the function attribute
86:ref:`no_sanitize_memory <langext-memory_sanitizer>`
87to disable uninitialized checks in a particular function.
88MemorySanitizer may still instrument such functions to avoid false positives.
89This attribute may not be
90supported by other compilers, so we suggest to use it together with
Evgeniy Stepanovfa203cf2013-08-15 13:57:11 +000091``__has_feature(memory_sanitizer)``.
Kostya Serebryany85aee962013-02-26 06:58:27 +000092
Alexey Samsonov05654ff2013-08-07 08:23:32 +000093Blacklist
94---------
95
96MemorySanitizer supports ``src`` and ``fun`` entity types in
97:doc:`SanitizerSpecialCaseList`, that can be used to relax MemorySanitizer
98checks for certain source files and functions. All "Use of uninitialized value"
99warnings will be suppressed and all values loaded from memory will be
100considered fully initialized.
101
Stephen Hines651f13c2014-04-23 16:59:28 -0700102Report symbolization
103====================
104
105MemorySanitizer uses an external symbolizer to print files and line numbers in
106reports. Make sure that ``llvm-symbolizer`` binary is in ``PATH``,
107or set environment variable ``MSAN_SYMBOLIZER_PATH`` to point to it.
108
Evgeniy Stepanovcc603e92012-12-21 10:50:00 +0000109Origin Tracking
110===============
111
112MemorySanitizer can track origins of unitialized values, similar to
113Valgrind's --track-origins option. This feature is enabled by
114``-fsanitize-memory-track-origins`` Clang option. With the code from
115the example above,
116
117.. code-block:: console
118
Peter Collingbourne52ca70d2013-04-09 04:35:11 +0000119 % clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -g -O2 umr.cc
Stephen Hines651f13c2014-04-23 16:59:28 -0700120 % ./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
Evgeniy Stepanovcc603e92012-12-21 10:50:00 +0000124
Stephen Hines651f13c2014-04-23 16:59:28 -0700125 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
129Origin tracking has proved to be very useful for debugging MemorySanitizer
Evgeniy Stepanovcc603e92012-12-21 10:50:00 +0000130reports. It slows down program execution by a factor of 1.5x-2x on top
131of the usual MemorySanitizer slowdown.
132
Stephen Hines651f13c2014-04-23 16:59:28 -0700133MemorySanitizer can provide even more information with
134``-fsanitize-memory-track-origins=2`` flag. In this mode reports
135include information about intermediate stores the uninitialized value went
136through.
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
Evgeniy Stepanovcc603e92012-12-21 10:50:00 +0000167Handling external code
168============================
169
170MemorySanitizer requires that all program code is instrumented. This
171also includes any libraries that the program depends on, even libc.
Stephen Hines651f13c2014-04-23 16:59:28 -0700172Failing to achieve this may result in false reports.
Evgeniy Stepanovcc603e92012-12-21 10:50:00 +0000173
174Full MemorySanitizer instrumentation is very difficult to achieve. To
175make it easier, MemorySanitizer runtime library includes 70+
176interceptors for the most common libc functions. They make it possible
177to run MemorySanitizer-instrumented programs linked with
178uninstrumented libc. For example, the authors were able to bootstrap
179MemorySanitizer-instrumented Clang compiler by linking it with
180self-built instrumented libcxx (as a replacement for libstdc++).
181
182In the case when rebuilding all program dependencies with
183MemorySanitizer is problematic, an experimental MSanDR tool can be
184used. It is a DynamoRio-based tool that uses dynamic instrumentation
185to avoid false positives due to uninstrumented code. The tool simply
186marks memory from instrumented libraries as fully initialized. See
187`http://code.google.com/p/memory-sanitizer/wiki/Running#Running_with_the_dynamic_tool`
188for more information.
189
190Supported Platforms
191===================
192
193MemorySanitizer is supported on
194
Stephen Hines651f13c2014-04-23 16:59:28 -0700195* Linux x86\_64 (tested on Ubuntu 12.04);
Evgeniy Stepanovcc603e92012-12-21 10:50:00 +0000196
197Limitations
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.
Peter Collingbourne52ca70d2013-04-09 04:35:11 +0000206* 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.
Evgeniy Stepanovcc603e92012-12-21 10:50:00 +0000210* 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
214Current Status
215==============
216
217MemorySanitizer is an experimental tool. It is known to work on large
218real-world programs, like Clang/LLVM itself.
219
220More Information
221================
222
223`http://code.google.com/p/memory-sanitizer <http://code.google.com/p/memory-sanitizer/>`_
224