[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / clang / docs / MemorySanitizer.rst
blobc6fc9407ea15ff9699be6769e1b6cb2e488c90ac
1 ================
2 MemorySanitizer
3 ================
5 .. contents::
6    :local:
8 Introduction
9 ============
11 MemorySanitizer is a detector of uninitialized reads. It consists of a
12 compiler instrumentation module and a run-time library.
14 Typical slowdown introduced by MemorySanitizer is **3x**.
16 How to build
17 ============
19 Build LLVM/Clang with `CMake <https://llvm.org/docs/CMake.html>`_.
21 Usage
22 =====
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``).
35 .. code-block:: console
37     % cat umr.cc
38     #include <stdio.h>
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     }
48     % clang -fsanitize=memory -fno-omit-frame-pointer -g -O2 umr.cc
50 If a bug is detected, the program will print an error message to
51 stderr and exit with a non-zero exit code.
53 .. code-block:: console
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
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>`.
64 ``__has_feature(memory_sanitizer)``
65 ------------------------------------
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.
71 .. code-block:: c
73     #if defined(__has_feature)
74     #  if __has_feature(memory_sanitizer)
75     // code that builds only under MemorySanitizer
76     #  endif
77     #endif
79 ``__attribute__((no_sanitize("memory")))``
80 -----------------------------------------------
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)``.
88 ``__attribute__((disable_sanitizer_instrumentation))``
89 --------------------------------------------------------
91 The ``disable_sanitizer_instrumentation`` attribute can be applied to functions
92 to prevent all kinds of instrumentation. As a result, it may introduce false
93 positives and therefore should be used with care, and only if absolutely
94 required; for example for certain code that cannot tolerate any instrumentation
95 and resulting side-effects. This attribute overrides ``no_sanitize("memory")``.
97 Ignorelist
98 ----------
100 MemorySanitizer supports ``src`` and ``fun`` entity types in
101 :doc:`SanitizerSpecialCaseList`, that can be used to relax MemorySanitizer
102 checks for certain source files and functions. All "Use of uninitialized value"
103 warnings will be suppressed and all values loaded from memory will be
104 considered fully initialized.
106 Report symbolization
107 ====================
109 MemorySanitizer uses an external symbolizer to print files and line numbers in
110 reports. Make sure that ``llvm-symbolizer`` binary is in ``PATH``,
111 or set environment variable ``MSAN_SYMBOLIZER_PATH`` to point to it.
113 .. _msan-origins:
115 Origin Tracking
116 ===============
118 MemorySanitizer can track origins of uninitialized values, similar to
119 Valgrind's --track-origins option. This feature is enabled by
120 ``-fsanitize-memory-track-origins=2`` (or simply
121 ``-fsanitize-memory-track-origins``) Clang option. With the code from
122 the example above,
124 .. code-block:: console
126     % cat umr2.cc
127     #include <stdio.h>
129     int main(int argc, char** argv) {
130       int* a = new int[10];
131       a[5] = 0;
132       volatile int b = a[argc];
133       if (b)
134         printf("xx\n");
135       return 0;
136     }
138     % clang -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O2 umr2.cc
139     % ./a.out
140     WARNING: MemorySanitizer: use-of-uninitialized-value
141         #0 0x7f7893912f0b in main umr2.cc:7
142         #1 0x7f789249b76c in __libc_start_main libc-start.c:226
144       Uninitialized value was stored to memory at
145         #0 0x7f78938b5c25 in __msan_chain_origin msan.cc:484
146         #1 0x7f7893912ecd in main umr2.cc:6
148       Uninitialized value was created by a heap allocation
149         #0 0x7f7893901cbd in operator new[](unsigned long) msan_new_delete.cc:44
150         #1 0x7f7893912e06 in main umr2.cc:4
152 By default, MemorySanitizer collects both allocation points and all
153 intermediate stores the uninitialized value went through.  Origin
154 tracking has proved to be very useful for debugging MemorySanitizer
155 reports. It slows down program execution by a factor of 1.5x-2x on top
156 of the usual MemorySanitizer slowdown and increases memory overhead.
158 Clang option ``-fsanitize-memory-track-origins=1`` enables a slightly
159 faster mode when MemorySanitizer collects only allocation points but
160 not intermediate stores.
162 Use-after-destruction detection
163 ===============================
165 You can enable experimental use-after-destruction detection in MemorySanitizer.
166 After invocation of the destructor, the object will be considered no longer
167 readable, and using underlying memory will lead to error reports in runtime.
169 This feature is still experimental, in order to enable it at runtime you need
172 #. Pass addition Clang option ``-fsanitize-memory-use-after-dtor`` during
173    compilation.
174 #. Set environment variable `MSAN_OPTIONS=poison_in_dtor=1` before running
175    the program.
177 Handling external code
178 ======================
180 MemorySanitizer requires that all program code is instrumented. This
181 also includes any libraries that the program depends on, even libc.
182 Failing to achieve this may result in false reports.
183 For the same reason you may need to replace all inline assembly code that writes to memory
184 with a pure C/C++ code.
186 Full MemorySanitizer instrumentation is very difficult to achieve. To
187 make it easier, MemorySanitizer runtime library includes 70+
188 interceptors for the most common libc functions. They make it possible
189 to run MemorySanitizer-instrumented programs linked with
190 uninstrumented libc. For example, the authors were able to bootstrap
191 MemorySanitizer-instrumented Clang compiler by linking it with
192 self-built instrumented libc++ (as a replacement for libstdc++).
194 Supported Platforms
195 ===================
197 MemorySanitizer is supported on the following OS:
199 * Linux
200 * NetBSD
201 * FreeBSD
203 Limitations
204 ===========
206 * MemorySanitizer uses 2x more real memory than a native run, 3x with
207   origin tracking.
208 * MemorySanitizer maps (but not reserves) 64 Terabytes of virtual
209   address space. This means that tools like ``ulimit`` may not work as
210   usually expected.
211 * Static linking is not supported.
212 * Older versions of MSan (LLVM 3.7 and older) didn't work with
213   non-position-independent executables, and could fail on some Linux
214   kernel versions with disabled ASLR. Refer to documentation for older versions
215   for more details.
216 * MemorySanitizer might be incompatible with position-independent executables
217   from FreeBSD 13 but there is a check done at runtime and throws a warning
218   in this case.
220 Current Status
221 ==============
223 MemorySanitizer is known to work on large real-world programs
224 (like Clang/LLVM itself) that can be recompiled from source, including all
225 dependent libraries.
227 More Information
228 ================
230 `<https://github.com/google/sanitizers/wiki/MemorySanitizer>`_