blob: 62cacce215d0c7bbab62cb021ea0cfba130aef98 [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
30higher. To get meaninful 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
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
Kostya Serebryany4c0fc992013-02-26 06:58:27 +000079``__attribute__((no_sanitize_memory))``
80-----------------------------------------------
81
Saleem Abdulrasool7f66d752015-10-19 01:24:08 +000082Some code should not be checked by MemorySanitizer. One may use the function
83attribute `no_sanitize_memory` to disable uninitialized checks in a particular
84function. MemorySanitizer may still instrument such functions to avoid false
85positives. This attribute may not be supported by other compilers, so we
86suggest 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.
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000174
175Full MemorySanitizer instrumentation is very difficult to achieve. To
176make it easier, MemorySanitizer runtime library includes 70+
177interceptors for the most common libc functions. They make it possible
178to run MemorySanitizer-instrumented programs linked with
179uninstrumented libc. For example, the authors were able to bootstrap
180MemorySanitizer-instrumented Clang compiler by linking it with
Evgeniy Stepanov5e927b62015-01-26 09:17:37 +0000181self-built instrumented libc++ (as a replacement for libstdc++).
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000182
183Supported Platforms
184===================
185
Alexey Samsonov1f7051e2015-12-04 22:50:44 +0000186MemorySanitizer is supported on Linux x86\_64/MIPS64/AArch64.
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000187
188Limitations
189===========
190
191* MemorySanitizer uses 2x more real memory than a native run, 3x with
192 origin tracking.
193* MemorySanitizer maps (but not reserves) 64 Terabytes of virtual
194 address space. This means that tools like ``ulimit`` may not work as
195 usually expected.
196* Static linking is not supported.
Alexey Samsonov1f7051e2015-12-04 22:50:44 +0000197* Older versions of MSan (LLVM 3.7 and older) didn't work with
198 non-position-independent executables, and could fail on some Linux
199 kernel versions with disabled ASLR. Refer to documentation for older versions
200 for more details.
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000201
202Current Status
203==============
204
Alexey Samsonov1f7051e2015-12-04 22:50:44 +0000205MemorySanitizer is known to work on large real-world programs
206(like Clang/LLVM itself) that can be recompiled from source, including all
207dependent libraries.
Evgeniy Stepanov17d55902012-12-21 10:50:00 +0000208
209More Information
210================
211
Alexey Samsonov2e2469d2015-12-04 00:38:13 +0000212`<https://github.com/google/sanitizers/wiki/MemorySanitizer>`_