xref: /aosp_15_r20/external/clang/docs/MemorySanitizer.rst (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li================
2*67e74705SXin LiMemorySanitizer
3*67e74705SXin Li================
4*67e74705SXin Li
5*67e74705SXin Li.. contents::
6*67e74705SXin Li   :local:
7*67e74705SXin Li
8*67e74705SXin LiIntroduction
9*67e74705SXin Li============
10*67e74705SXin Li
11*67e74705SXin LiMemorySanitizer is a detector of uninitialized reads. It consists of a
12*67e74705SXin Licompiler instrumentation module and a run-time library.
13*67e74705SXin Li
14*67e74705SXin LiTypical slowdown introduced by MemorySanitizer is **3x**.
15*67e74705SXin Li
16*67e74705SXin LiHow to build
17*67e74705SXin Li============
18*67e74705SXin Li
19*67e74705SXin LiBuild LLVM/Clang with `CMake <http://llvm.org/docs/CMake.html>`_.
20*67e74705SXin Li
21*67e74705SXin LiUsage
22*67e74705SXin Li=====
23*67e74705SXin Li
24*67e74705SXin LiSimply compile and link your program with ``-fsanitize=memory`` flag.
25*67e74705SXin LiThe MemorySanitizer run-time library should be linked to the final
26*67e74705SXin Liexecutable, so make sure to use ``clang`` (not ``ld``) for the final
27*67e74705SXin Lilink step. When linking shared libraries, the MemorySanitizer run-time
28*67e74705SXin Liis not linked, so ``-Wl,-z,defs`` may cause link errors (don't use it
29*67e74705SXin Liwith MemorySanitizer). To get a reasonable performance add ``-O1`` or
30*67e74705SXin Lihigher. To get meaninful stack traces in error messages add
31*67e74705SXin Li``-fno-omit-frame-pointer``. To get perfect stack traces you may need
32*67e74705SXin Lito disable inlining (just use ``-O1``) and tail call elimination
33*67e74705SXin Li(``-fno-optimize-sibling-calls``).
34*67e74705SXin Li
35*67e74705SXin Li.. code-block:: console
36*67e74705SXin Li
37*67e74705SXin Li    % cat umr.cc
38*67e74705SXin Li    #include <stdio.h>
39*67e74705SXin Li
40*67e74705SXin Li    int main(int argc, char** argv) {
41*67e74705SXin Li      int* a = new int[10];
42*67e74705SXin Li      a[5] = 0;
43*67e74705SXin Li      if (a[argc])
44*67e74705SXin Li        printf("xx\n");
45*67e74705SXin Li      return 0;
46*67e74705SXin Li    }
47*67e74705SXin Li
48*67e74705SXin Li    % clang -fsanitize=memory -fno-omit-frame-pointer -g -O2 umr.cc
49*67e74705SXin Li
50*67e74705SXin LiIf a bug is detected, the program will print an error message to
51*67e74705SXin Listderr and exit with a non-zero exit code.
52*67e74705SXin Li
53*67e74705SXin Li.. code-block:: console
54*67e74705SXin Li
55*67e74705SXin Li    % ./a.out
56*67e74705SXin Li    WARNING: MemorySanitizer: use-of-uninitialized-value
57*67e74705SXin Li        #0 0x7f45944b418a in main umr.cc:6
58*67e74705SXin Li        #1 0x7f45938b676c in __libc_start_main libc-start.c:226
59*67e74705SXin Li
60*67e74705SXin LiBy default, MemorySanitizer exits on the first detected error. If you
61*67e74705SXin Lifind the error report hard to understand, try enabling
62*67e74705SXin Li:ref:`origin tracking <msan-origins>`.
63*67e74705SXin Li
64*67e74705SXin Li``__has_feature(memory_sanitizer)``
65*67e74705SXin Li------------------------------------
66*67e74705SXin Li
67*67e74705SXin LiIn some cases one may need to execute different code depending on
68*67e74705SXin Liwhether MemorySanitizer is enabled. :ref:`\_\_has\_feature
69*67e74705SXin Li<langext-__has_feature-__has_extension>` can be used for this purpose.
70*67e74705SXin Li
71*67e74705SXin Li.. code-block:: c
72*67e74705SXin Li
73*67e74705SXin Li    #if defined(__has_feature)
74*67e74705SXin Li    #  if __has_feature(memory_sanitizer)
75*67e74705SXin Li    // code that builds only under MemorySanitizer
76*67e74705SXin Li    #  endif
77*67e74705SXin Li    #endif
78*67e74705SXin Li
79*67e74705SXin Li``__attribute__((no_sanitize_memory))``
80*67e74705SXin Li-----------------------------------------------
81*67e74705SXin Li
82*67e74705SXin LiSome code should not be checked by MemorySanitizer.  One may use the function
83*67e74705SXin Liattribute `no_sanitize_memory` to disable uninitialized checks in a particular
84*67e74705SXin Lifunction.  MemorySanitizer may still instrument such functions to avoid false
85*67e74705SXin Lipositives.  This attribute may not be supported by other compilers, so we
86*67e74705SXin Lisuggest to use it together with ``__has_feature(memory_sanitizer)``.
87*67e74705SXin Li
88*67e74705SXin LiBlacklist
89*67e74705SXin Li---------
90*67e74705SXin Li
91*67e74705SXin LiMemorySanitizer supports ``src`` and ``fun`` entity types in
92*67e74705SXin Li:doc:`SanitizerSpecialCaseList`, that can be used to relax MemorySanitizer
93*67e74705SXin Lichecks for certain source files and functions. All "Use of uninitialized value"
94*67e74705SXin Liwarnings will be suppressed and all values loaded from memory will be
95*67e74705SXin Liconsidered fully initialized.
96*67e74705SXin Li
97*67e74705SXin LiReport symbolization
98*67e74705SXin Li====================
99*67e74705SXin Li
100*67e74705SXin LiMemorySanitizer uses an external symbolizer to print files and line numbers in
101*67e74705SXin Lireports. Make sure that ``llvm-symbolizer`` binary is in ``PATH``,
102*67e74705SXin Lior set environment variable ``MSAN_SYMBOLIZER_PATH`` to point to it.
103*67e74705SXin Li
104*67e74705SXin Li.. _msan-origins:
105*67e74705SXin Li
106*67e74705SXin LiOrigin Tracking
107*67e74705SXin Li===============
108*67e74705SXin Li
109*67e74705SXin LiMemorySanitizer can track origins of uninitialized values, similar to
110*67e74705SXin LiValgrind's --track-origins option. This feature is enabled by
111*67e74705SXin Li``-fsanitize-memory-track-origins=2`` (or simply
112*67e74705SXin Li``-fsanitize-memory-track-origins``) Clang option. With the code from
113*67e74705SXin Lithe example above,
114*67e74705SXin Li
115*67e74705SXin Li.. code-block:: console
116*67e74705SXin Li
117*67e74705SXin Li    % cat umr2.cc
118*67e74705SXin Li    #include <stdio.h>
119*67e74705SXin Li
120*67e74705SXin Li    int main(int argc, char** argv) {
121*67e74705SXin Li      int* a = new int[10];
122*67e74705SXin Li      a[5] = 0;
123*67e74705SXin Li      volatile int b = a[argc];
124*67e74705SXin Li      if (b)
125*67e74705SXin Li        printf("xx\n");
126*67e74705SXin Li      return 0;
127*67e74705SXin Li    }
128*67e74705SXin Li
129*67e74705SXin Li    % clang -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O2 umr2.cc
130*67e74705SXin Li    % ./a.out
131*67e74705SXin Li    WARNING: MemorySanitizer: use-of-uninitialized-value
132*67e74705SXin Li        #0 0x7f7893912f0b in main umr2.cc:7
133*67e74705SXin Li        #1 0x7f789249b76c in __libc_start_main libc-start.c:226
134*67e74705SXin Li
135*67e74705SXin Li      Uninitialized value was stored to memory at
136*67e74705SXin Li        #0 0x7f78938b5c25 in __msan_chain_origin msan.cc:484
137*67e74705SXin Li        #1 0x7f7893912ecd in main umr2.cc:6
138*67e74705SXin Li
139*67e74705SXin Li      Uninitialized value was created by a heap allocation
140*67e74705SXin Li        #0 0x7f7893901cbd in operator new[](unsigned long) msan_new_delete.cc:44
141*67e74705SXin Li        #1 0x7f7893912e06 in main umr2.cc:4
142*67e74705SXin Li
143*67e74705SXin LiBy default, MemorySanitizer collects both allocation points and all
144*67e74705SXin Liintermediate stores the uninitialized value went through.  Origin
145*67e74705SXin Litracking has proved to be very useful for debugging MemorySanitizer
146*67e74705SXin Lireports. It slows down program execution by a factor of 1.5x-2x on top
147*67e74705SXin Liof the usual MemorySanitizer slowdown and increases memory overhead.
148*67e74705SXin Li
149*67e74705SXin LiClang option ``-fsanitize-memory-track-origins=1`` enables a slightly
150*67e74705SXin Lifaster mode when MemorySanitizer collects only allocation points but
151*67e74705SXin Linot intermediate stores.
152*67e74705SXin Li
153*67e74705SXin LiUse-after-destruction detection
154*67e74705SXin Li===============================
155*67e74705SXin Li
156*67e74705SXin LiYou can enable experimental use-after-destruction detection in MemorySanitizer.
157*67e74705SXin LiAfter invocation of the destructor, the object will be considered no longer
158*67e74705SXin Lireadable, and using underlying memory will lead to error reports in runtime.
159*67e74705SXin Li
160*67e74705SXin LiThis feature is still experimental, in order to enable it at runtime you need
161*67e74705SXin Lito:
162*67e74705SXin Li
163*67e74705SXin Li#. Pass addition Clang option ``-fsanitize-memory-use-after-dtor`` during
164*67e74705SXin Li   compilation.
165*67e74705SXin Li#. Set environment variable `MSAN_OPTIONS=poison_in_dtor=1` before running
166*67e74705SXin Li   the program.
167*67e74705SXin Li
168*67e74705SXin LiHandling external code
169*67e74705SXin Li======================
170*67e74705SXin Li
171*67e74705SXin LiMemorySanitizer requires that all program code is instrumented. This
172*67e74705SXin Lialso includes any libraries that the program depends on, even libc.
173*67e74705SXin LiFailing to achieve this may result in false reports.
174*67e74705SXin LiFor the same reason you may need to replace all inline assembly code that writes to memory
175*67e74705SXin Liwith a pure C/C++ code.
176*67e74705SXin Li
177*67e74705SXin LiFull MemorySanitizer instrumentation is very difficult to achieve. To
178*67e74705SXin Limake it easier, MemorySanitizer runtime library includes 70+
179*67e74705SXin Liinterceptors for the most common libc functions. They make it possible
180*67e74705SXin Lito run MemorySanitizer-instrumented programs linked with
181*67e74705SXin Liuninstrumented libc. For example, the authors were able to bootstrap
182*67e74705SXin LiMemorySanitizer-instrumented Clang compiler by linking it with
183*67e74705SXin Liself-built instrumented libc++ (as a replacement for libstdc++).
184*67e74705SXin Li
185*67e74705SXin LiSupported Platforms
186*67e74705SXin Li===================
187*67e74705SXin Li
188*67e74705SXin LiMemorySanitizer is supported on Linux x86\_64/MIPS64/AArch64.
189*67e74705SXin Li
190*67e74705SXin LiLimitations
191*67e74705SXin Li===========
192*67e74705SXin Li
193*67e74705SXin Li* MemorySanitizer uses 2x more real memory than a native run, 3x with
194*67e74705SXin Li  origin tracking.
195*67e74705SXin Li* MemorySanitizer maps (but not reserves) 64 Terabytes of virtual
196*67e74705SXin Li  address space. This means that tools like ``ulimit`` may not work as
197*67e74705SXin Li  usually expected.
198*67e74705SXin Li* Static linking is not supported.
199*67e74705SXin Li* Older versions of MSan (LLVM 3.7 and older) didn't work with
200*67e74705SXin Li  non-position-independent executables, and could fail on some Linux
201*67e74705SXin Li  kernel versions with disabled ASLR. Refer to documentation for older versions
202*67e74705SXin Li  for more details.
203*67e74705SXin Li
204*67e74705SXin LiCurrent Status
205*67e74705SXin Li==============
206*67e74705SXin Li
207*67e74705SXin LiMemorySanitizer is known to work on large real-world programs
208*67e74705SXin Li(like Clang/LLVM itself) that can be recompiled from source, including all
209*67e74705SXin Lidependent libraries.
210*67e74705SXin Li
211*67e74705SXin LiMore Information
212*67e74705SXin Li================
213*67e74705SXin Li
214*67e74705SXin Li`<https://github.com/google/sanitizers/wiki/MemorySanitizer>`_
215