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