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