]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - docs/MemorySanitizer.rst
Vendor import of clang trunk r338150:
[FreeBSD/FreeBSD.git] / docs / MemorySanitizer.rst
1 ================
2 MemorySanitizer
3 ================
4
5 .. contents::
6    :local:
7
8 Introduction
9 ============
10
11 MemorySanitizer is a detector of uninitialized reads. It consists of a
12 compiler instrumentation module and a run-time library.
13
14 Typical slowdown introduced by MemorySanitizer is **3x**.
15
16 How to build
17 ============
18
19 Build LLVM/Clang with `CMake <http://llvm.org/docs/CMake.html>`_.
20
21 Usage
22 =====
23
24 Simply compile and link your program with ``-fsanitize=memory`` flag.
25 The MemorySanitizer run-time library should be linked to the final
26 executable, so make sure to use ``clang`` (not ``ld``) for the final
27 link step. When linking shared libraries, the MemorySanitizer run-time
28 is not linked, so ``-Wl,-z,defs`` may cause link errors (don't use it
29 with MemorySanitizer). To get a reasonable performance add ``-O1`` or
30 higher. To get meaningful stack traces in error messages add
31 ``-fno-omit-frame-pointer``. To get perfect stack traces you may need
32 to 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
50 If a bug is detected, the program will print an error message to
51 stderr 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
60 By default, MemorySanitizer exits on the first detected error. If you
61 find the error report hard to understand, try enabling
62 :ref:`origin tracking <msan-origins>`.
63
64 ``__has_feature(memory_sanitizer)``
65 ------------------------------------
66
67 In some cases one may need to execute different code depending on
68 whether 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
82 Some code should not be checked by MemorySanitizer.  One may use the function
83 attribute ``no_sanitize("memory")`` to disable uninitialized checks in a
84 particular function.  MemorySanitizer may still instrument such functions to
85 avoid false positives.  This attribute may not be supported by other compilers,
86 so we suggest to use it together with ``__has_feature(memory_sanitizer)``.
87
88 Blacklist
89 ---------
90
91 MemorySanitizer supports ``src`` and ``fun`` entity types in
92 :doc:`SanitizerSpecialCaseList`, that can be used to relax MemorySanitizer
93 checks for certain source files and functions. All "Use of uninitialized value"
94 warnings will be suppressed and all values loaded from memory will be
95 considered fully initialized.
96
97 Report symbolization
98 ====================
99
100 MemorySanitizer uses an external symbolizer to print files and line numbers in
101 reports. Make sure that ``llvm-symbolizer`` binary is in ``PATH``,
102 or set environment variable ``MSAN_SYMBOLIZER_PATH`` to point to it.
103
104 .. _msan-origins:
105
106 Origin Tracking
107 ===============
108
109 MemorySanitizer can track origins of uninitialized values, similar to
110 Valgrind's --track-origins option. This feature is enabled by
111 ``-fsanitize-memory-track-origins=2`` (or simply
112 ``-fsanitize-memory-track-origins``) Clang option. With the code from
113 the example above,
114
115 .. code-block:: console
116
117     % 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
143 By default, MemorySanitizer collects both allocation points and all
144 intermediate stores the uninitialized value went through.  Origin
145 tracking has proved to be very useful for debugging MemorySanitizer
146 reports. It slows down program execution by a factor of 1.5x-2x on top
147 of the usual MemorySanitizer slowdown and increases memory overhead.
148
149 Clang option ``-fsanitize-memory-track-origins=1`` enables a slightly
150 faster mode when MemorySanitizer collects only allocation points but
151 not intermediate stores.
152
153 Use-after-destruction detection
154 ===============================
155
156 You can enable experimental use-after-destruction detection in MemorySanitizer.
157 After invocation of the destructor, the object will be considered no longer
158 readable, and using underlying memory will lead to error reports in runtime.
159
160 This feature is still experimental, in order to enable it at runtime you need
161 to:
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
168 Handling external code
169 ======================
170
171 MemorySanitizer requires that all program code is instrumented. This
172 also includes any libraries that the program depends on, even libc.
173 Failing to achieve this may result in false reports.
174 For the same reason you may need to replace all inline assembly code that writes to memory
175 with a pure C/C++ code.
176
177 Full MemorySanitizer instrumentation is very difficult to achieve. To
178 make it easier, MemorySanitizer runtime library includes 70+
179 interceptors for the most common libc functions. They make it possible
180 to run MemorySanitizer-instrumented programs linked with
181 uninstrumented libc. For example, the authors were able to bootstrap
182 MemorySanitizer-instrumented Clang compiler by linking it with
183 self-built instrumented libc++ (as a replacement for libstdc++).
184
185 Supported Platforms
186 ===================
187
188 MemorySanitizer is supported on the following OS:
189
190 * Linux
191 * NetBSD
192 * FreeBSD
193
194 Limitations
195 ===========
196
197 * MemorySanitizer uses 2x more real memory than a native run, 3x with
198   origin tracking.
199 * MemorySanitizer maps (but not reserves) 64 Terabytes of virtual
200   address space. This means that tools like ``ulimit`` may not work as
201   usually expected.
202 * Static linking is not supported.
203 * Older versions of MSan (LLVM 3.7 and older) didn't work with
204   non-position-independent executables, and could fail on some Linux
205   kernel versions with disabled ASLR. Refer to documentation for older versions
206   for more details.
207
208 Current Status
209 ==============
210
211 MemorySanitizer is known to work on large real-world programs
212 (like Clang/LLVM itself) that can be recompiled from source, including all
213 dependent libraries.
214
215 More Information
216 ================
217
218 `<https://github.com/google/sanitizers/wiki/MemorySanitizer>`_