xref: /llvm-project/clang/docs/AddressSanitizer.rst (revision 64c455077abe583f96fc19398712da9c1187ad61)
1================
2AddressSanitizer
3================
4
5.. contents::
6   :local:
7
8Introduction
9============
10
11AddressSanitizer is a fast memory error detector. It consists of a compiler
12instrumentation module and a run-time library. The tool can detect the
13following types of bugs:
14
15* Out-of-bounds accesses to heap, stack and globals
16* Use-after-free
17* Use-after-return (clang flag ``-fsanitize-address-use-after-return=(never|runtime|always)`` default: ``runtime``)
18    * Enable with: ``ASAN_OPTIONS=detect_stack_use_after_return=1`` (already enabled on Linux).
19    * Disable with: ``ASAN_OPTIONS=detect_stack_use_after_return=0``.
20* Use-after-scope (clang flag ``-fsanitize-address-use-after-scope``)
21* Double-free, invalid free
22* Memory leaks (experimental)
23
24Typical slowdown introduced by AddressSanitizer is **2x**.
25
26How to build
27============
28
29Build LLVM/Clang with `CMake <https://llvm.org/docs/CMake.html>`_ and enable
30the ``compiler-rt`` runtime. An example CMake configuration that will allow
31for the use/testing of AddressSanitizer:
32
33.. code-block:: console
34
35   $ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_ENABLE_RUNTIMES="compiler-rt" <path to source>/llvm
36
37Usage
38=====
39
40Simply compile and link your program with ``-fsanitize=address`` flag.  The
41AddressSanitizer run-time library should be linked to the final executable, so
42make sure to use ``clang`` (not ``ld``) for the final link step.  When linking
43shared libraries, the AddressSanitizer run-time is not linked, so
44``-Wl,-z,defs`` may cause link errors (don't use it with AddressSanitizer).  To
45get a reasonable performance add ``-O1`` or higher.  To get nicer stack traces
46in error messages add ``-fno-omit-frame-pointer``.  To get perfect stack traces
47you may need to disable inlining (just use ``-O1``) and tail call elimination
48(``-fno-optimize-sibling-calls``).
49
50.. code-block:: console
51
52    % cat example_UseAfterFree.cc
53    int main(int argc, char **argv) {
54      int *array = new int[100];
55      delete [] array;
56      return array[argc];  // BOOM
57    }
58
59    # Compile and link
60    % clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc
61
62or:
63
64.. code-block:: console
65
66    # Compile
67    % clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer -c example_UseAfterFree.cc
68    # Link
69    % clang++ -g -fsanitize=address example_UseAfterFree.o
70
71If a bug is detected, the program will print an error message to stderr and
72exit with a non-zero exit code. AddressSanitizer exits on the first detected error.
73This is by design:
74
75* This approach allows AddressSanitizer to produce faster and smaller generated code
76  (both by ~5%).
77* Fixing bugs becomes unavoidable. AddressSanitizer does not produce
78  false alarms. Once a memory corruption occurs, the program is in an inconsistent
79  state, which could lead to confusing results and potentially misleading
80  subsequent reports.
81
82If your process is sandboxed and you are running on OS X 10.10 or earlier, you
83will need to set ``DYLD_INSERT_LIBRARIES`` environment variable and point it to
84the ASan library that is packaged with the compiler used to build the
85executable. (You can find the library by searching for dynamic libraries with
86``asan`` in their name.) If the environment variable is not set, the process will
87try to re-exec. Also keep in mind that when moving the executable to another machine,
88the ASan library will also need to be copied over.
89
90Symbolizing the Reports
91=========================
92
93To make AddressSanitizer symbolize its output
94you need to set the ``ASAN_SYMBOLIZER_PATH`` environment variable to point to
95the ``llvm-symbolizer`` binary (or make sure ``llvm-symbolizer`` is in your
96``$PATH``):
97
98.. code-block:: console
99
100    % ASAN_SYMBOLIZER_PATH=/usr/local/bin/llvm-symbolizer ./a.out
101    ==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8
102    READ of size 4 at 0x7f7ddab8c084 thread T0
103        #0 0x403c8c in main example_UseAfterFree.cc:4
104        #1 0x7f7ddabcac4d in __libc_start_main ??:0
105    0x7f7ddab8c084 is located 4 bytes inside of 400-byte region [0x7f7ddab8c080,0x7f7ddab8c210)
106    freed by thread T0 here:
107        #0 0x404704 in operator delete[](void*) ??:0
108        #1 0x403c53 in main example_UseAfterFree.cc:4
109        #2 0x7f7ddabcac4d in __libc_start_main ??:0
110    previously allocated by thread T0 here:
111        #0 0x404544 in operator new[](unsigned long) ??:0
112        #1 0x403c43 in main example_UseAfterFree.cc:2
113        #2 0x7f7ddabcac4d in __libc_start_main ??:0
114    ==9442== ABORTING
115
116If that does not work for you (e.g. your process is sandboxed), you can use a
117separate script to symbolize the result offline (online symbolization can be
118force disabled by setting ``ASAN_OPTIONS=symbolize=0``):
119
120.. code-block:: console
121
122    % ASAN_OPTIONS=symbolize=0 ./a.out 2> log
123    % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt
124    ==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8
125    READ of size 4 at 0x7f7ddab8c084 thread T0
126        #0 0x403c8c in main example_UseAfterFree.cc:4
127        #1 0x7f7ddabcac4d in __libc_start_main ??:0
128    ...
129
130Note that on macOS you may need to run ``dsymutil`` on your binary to have the
131file\:line info in the AddressSanitizer reports.
132
133Additional Checks
134=================
135
136Initialization order checking
137-----------------------------
138
139AddressSanitizer can optionally detect dynamic initialization order problems,
140when initialization of globals defined in one translation unit uses
141globals defined in another translation unit. To enable this check at runtime,
142you should set environment variable
143``ASAN_OPTIONS=check_initialization_order=1``.
144
145Note that this option is not supported on macOS.
146
147Stack Use After Return (UAR)
148----------------------------
149
150AddressSanitizer can optionally detect stack use after return problems.
151This is available by default, or explicitly
152(``-fsanitize-address-use-after-return=runtime``).
153To disable this check at runtime, set the environment variable
154``ASAN_OPTIONS=detect_stack_use_after_return=0``.
155
156Enabling this check (``-fsanitize-address-use-after-return=always``) will
157reduce code size.  The code size may be reduced further by completely
158eliminating this check (``-fsanitize-address-use-after-return=never``).
159
160To summarize: ``-fsanitize-address-use-after-return=<mode>``
161  * ``never``: Completely disables detection of UAR errors (reduces code size).
162  * ``runtime``: Adds the code for detection, but it can be disable via the
163    runtime environment (``ASAN_OPTIONS=detect_stack_use_after_return=0``).
164  * ``always``: Enables detection of UAR errors in all cases. (reduces code
165    size, but not as much as ``never``).
166
167Memory leak detection
168---------------------
169
170For more information on leak detector in AddressSanitizer, see
171:doc:`LeakSanitizer`. The leak detection is turned on by default on Linux,
172and can be enabled using ``ASAN_OPTIONS=detect_leaks=1`` on macOS;
173however, it is not yet supported on other platforms.
174
175Issue Suppression
176=================
177
178AddressSanitizer is not expected to produce false positives. If you see one,
179look again; most likely it is a true positive!
180
181Suppressing Reports in External Libraries
182-----------------------------------------
183Runtime interposition allows AddressSanitizer to find bugs in code that is
184not being recompiled. If you run into an issue in external libraries, we
185recommend immediately reporting it to the library maintainer so that it
186gets addressed. However, you can use the following suppression mechanism
187to unblock yourself and continue on with the testing. This suppression
188mechanism should only be used for suppressing issues in external code; it
189does not work on code recompiled with AddressSanitizer. To suppress errors
190in external libraries, set the ``ASAN_OPTIONS`` environment variable to point
191to a suppression file. You can either specify the full path to the file or the
192path of the file relative to the location of your executable.
193
194.. code-block:: bash
195
196    ASAN_OPTIONS=suppressions=MyASan.supp
197
198Use the following format to specify the names of the functions or libraries
199you want to suppress. You can see these in the error report. Remember that
200the narrower the scope of the suppression, the more bugs you will be able to
201catch.
202
203.. code-block:: bash
204
205    interceptor_via_fun:NameOfCFunctionToSuppress
206    interceptor_via_fun:-[ClassName objCMethodToSuppress:]
207    interceptor_via_lib:NameOfTheLibraryToSuppress
208
209Conditional Compilation with ``__has_feature(address_sanitizer)``
210-----------------------------------------------------------------
211
212In some cases one may need to execute different code depending on whether
213AddressSanitizer is enabled.
214:ref:`\_\_has\_feature <langext-__has_feature-__has_extension>` can be used for
215this purpose.
216
217.. code-block:: c
218
219    #if defined(__has_feature)
220    #  if __has_feature(address_sanitizer)
221    // code that builds only under AddressSanitizer
222    #  endif
223    #endif
224
225Disabling Instrumentation with ``__attribute__((no_sanitize("address")))``
226--------------------------------------------------------------------------
227
228Some code should not be instrumented by AddressSanitizer. One may use
229the attribute ``__attribute__((no_sanitize("address")))`` (which has
230deprecated synonyms `no_sanitize_address` and
231`no_address_safety_analysis`) to disable instrumentation of a
232particular function. This attribute may not be supported by other
233compilers, so we suggest to use it together with
234``__has_feature(address_sanitizer)``.
235
236The same attribute used on a global variable prevents AddressSanitizer
237from adding redzones around it and detecting out of bounds accesses.
238
239
240AddressSanitizer also supports
241``__attribute__((disable_sanitizer_instrumentation))``. This attribute
242works similar to ``__attribute__((no_sanitize("address")))``, but it also
243prevents instrumentation performed by other sanitizers.
244
245Suppressing Errors in Recompiled Code (Ignorelist)
246--------------------------------------------------
247
248AddressSanitizer supports ``src`` and ``fun`` entity types in
249:doc:`SanitizerSpecialCaseList`, that can be used to suppress error reports
250in the specified source files or functions. Additionally, AddressSanitizer
251introduces ``global`` and ``type`` entity types that can be used to
252suppress error reports for out-of-bound access to globals with certain
253names and types (you may only specify class or struct types).
254
255You may use an ``init`` category to suppress reports about initialization-order
256problems happening in certain source files or with certain global variables.
257
258.. code-block:: bash
259
260    # Suppress error reports for code in a file or in a function:
261    src:bad_file.cpp
262    # Ignore all functions with names containing MyFooBar:
263    fun:*MyFooBar*
264    # Disable out-of-bound checks for global:
265    global:bad_array
266    # Disable out-of-bound checks for global instances of a given class ...
267    type:Namespace::BadClassName
268    # ... or a given struct. Use wildcard to deal with anonymous namespace.
269    type:Namespace2::*::BadStructName
270    # Disable initialization-order checks for globals:
271    global:bad_init_global=init
272    type:*BadInitClassSubstring*=init
273    src:bad/init/files/*=init
274
275Suppressing memory leaks
276------------------------
277
278Memory leak reports produced by :doc:`LeakSanitizer` (if it is run as a part
279of AddressSanitizer) can be suppressed by a separate file passed as
280
281.. code-block:: bash
282
283    LSAN_OPTIONS=suppressions=MyLSan.supp
284
285which contains lines of the form `leak:<pattern>`. Memory leak will be
286suppressed if pattern matches any function name, source file name, or
287library name in the symbolized stack trace of the leak report. See
288`full documentation
289<https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#suppressions>`_
290for more details.
291
292Code generation control
293=======================
294
295Instrumentation code outlining
296------------------------------
297
298By default AddressSanitizer inlines the instrumentation code to improve the
299run-time performance, which leads to increased binary size. Using the
300(clang flag ``-fsanitize-address-outline-instrumentation` default: ``false``)
301flag forces all code instrumentation to be outlined, which reduces the size
302of the generated code, but also reduces the run-time performance.
303
304Limitations
305===========
306
307* AddressSanitizer uses more real memory than a native run. Exact overhead
308  depends on the allocations sizes. The smaller the allocations you make the
309  bigger the overhead is.
310* AddressSanitizer uses more stack memory. We have seen up to 3x increase.
311* On 64-bit platforms AddressSanitizer maps (but not reserves) 16+ Terabytes of
312  virtual address space. This means that tools like ``ulimit`` may not work as
313  usually expected.
314* Static linking of executables is not supported.
315
316Security Considerations
317=======================
318
319AddressSanitizer is a bug detection tool and its runtime is not meant to be
320linked against production executables. While it may be useful for testing,
321AddressSanitizer's runtime was not developed with security-sensitive
322constraints in mind and may compromise the security of the resulting executable.
323
324Supported Platforms
325===================
326
327AddressSanitizer is supported on:
328
329* Linux
330* macOS
331* iOS Simulator
332* Android
333* NetBSD
334* FreeBSD
335* Windows 8.1+
336
337Current Status
338==============
339
340AddressSanitizer is fully functional on supported platforms starting from LLVM
3413.1. The test suite is integrated into CMake build and can be run with ``make
342check-asan`` command.
343
344The Windows port is functional and is used by Chrome and Firefox, but it is not
345as well supported as the other ports.
346
347More Information
348================
349
350`<https://github.com/google/sanitizers/wiki/AddressSanitizer>`_
351