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 <http://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 OS X 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 OS X.
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 OS X;
145however, it is not yet supported on other platforms.
146
147Writable/Executable paging detection
148------------------------------------
149
150The W^X detection is disabled by default and can be enabled using
151``ASAN_OPTIONS=detect_write_exec=1``.
152
153Issue Suppression
154=================
155
156AddressSanitizer is not expected to produce false positives. If you see one,
157look again; most likely it is a true positive!
158
159Suppressing Reports in External Libraries
160-----------------------------------------
161Runtime interposition allows AddressSanitizer to find bugs in code that is
162not being recompiled. If you run into an issue in external libraries, we
163recommend immediately reporting it to the library maintainer so that it
164gets addressed. However, you can use the following suppression mechanism
165to unblock yourself and continue on with the testing. This suppression
166mechanism should only be used for suppressing issues in external code; it
167does not work on code recompiled with AddressSanitizer. To suppress errors
168in external libraries, set the ``ASAN_OPTIONS`` environment variable to point
169to a suppression file. You can either specify the full path to the file or the
170path of the file relative to the location of your executable.
171
172.. code-block:: bash
173
174    ASAN_OPTIONS=suppressions=MyASan.supp
175
176Use the following format to specify the names of the functions or libraries
177you want to suppress. You can see these in the error report. Remember that
178the narrower the scope of the suppression, the more bugs you will be able to
179catch.
180
181.. code-block:: bash
182
183    interceptor_via_fun:NameOfCFunctionToSuppress
184    interceptor_via_fun:-[ClassName objCMethodToSuppress:]
185    interceptor_via_lib:NameOfTheLibraryToSuppress
186
187Conditional Compilation with ``__has_feature(address_sanitizer)``
188-----------------------------------------------------------------
189
190In some cases one may need to execute different code depending on whether
191AddressSanitizer is enabled.
192:ref:`\_\_has\_feature <langext-__has_feature-__has_extension>` can be used for
193this purpose.
194
195.. code-block:: c
196
197    #if defined(__has_feature)
198    #  if __has_feature(address_sanitizer)
199    // code that builds only under AddressSanitizer
200    #  endif
201    #endif
202
203Disabling Instrumentation with ``__attribute__((no_sanitize("address")))``
204--------------------------------------------------------------------------
205
206Some code should not be instrumented by AddressSanitizer. One may use
207the attribute ``__attribute__((no_sanitize("address")))`` (which has
208deprecated synonyms `no_sanitize_address` and
209`no_address_safety_analysis`) to disable instrumentation of a
210particular function. This attribute may not be supported by other
211compilers, so we suggest to use it together with
212``__has_feature(address_sanitizer)``.
213
214The same attribute used on a global variable prevents AddressSanitizer
215from adding redzones around it and detecting out of bounds accesses.
216
217Suppressing Errors in Recompiled Code (Blacklist)
218-------------------------------------------------
219
220AddressSanitizer supports ``src`` and ``fun`` entity types in
221:doc:`SanitizerSpecialCaseList`, that can be used to suppress error reports
222in the specified source files or functions. Additionally, AddressSanitizer
223introduces ``global`` and ``type`` entity types that can be used to
224suppress error reports for out-of-bound access to globals with certain
225names and types (you may only specify class or struct types).
226
227You may use an ``init`` category to suppress reports about initialization-order
228problems happening in certain source files or with certain global variables.
229
230.. code-block:: bash
231
232    # Suppress error reports for code in a file or in a function:
233    src:bad_file.cpp
234    # Ignore all functions with names containing MyFooBar:
235    fun:*MyFooBar*
236    # Disable out-of-bound checks for global:
237    global:bad_array
238    # Disable out-of-bound checks for global instances of a given class ...
239    type:Namespace::BadClassName
240    # ... or a given struct. Use wildcard to deal with anonymous namespace.
241    type:Namespace2::*::BadStructName
242    # Disable initialization-order checks for globals:
243    global:bad_init_global=init
244    type:*BadInitClassSubstring*=init
245    src:bad/init/files/*=init
246
247Suppressing memory leaks
248------------------------
249
250Memory leak reports produced by :doc:`LeakSanitizer` (if it is run as a part
251of AddressSanitizer) can be suppressed by a separate file passed as
252
253.. code-block:: bash
254
255    LSAN_OPTIONS=suppressions=MyLSan.supp
256
257which contains lines of the form `leak:<pattern>`. Memory leak will be
258suppressed if pattern matches any function name, source file name, or
259library name in the symbolized stack trace of the leak report. See
260`full documentation
261<https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#suppressions>`_
262for more details.
263
264Limitations
265===========
266
267* AddressSanitizer uses more real memory than a native run. Exact overhead
268  depends on the allocations sizes. The smaller the allocations you make the
269  bigger the overhead is.
270* AddressSanitizer uses more stack memory. We have seen up to 3x increase.
271* On 64-bit platforms AddressSanitizer maps (but not reserves) 16+ Terabytes of
272  virtual address space. This means that tools like ``ulimit`` may not work as
273  usually expected.
274* Static linking is not supported.
275
276Supported Platforms
277===================
278
279AddressSanitizer is supported on:
280
281* Linux i386/x86\_64 (tested on Ubuntu 12.04)
282* OS X 10.7 - 10.11 (i386/x86\_64)
283* iOS Simulator
284* Android ARM
285* NetBSD i386/x86\_64
286* FreeBSD i386/x86\_64 (tested on FreeBSD 11-current)
287
288Ports to various other platforms are in progress.
289
290Current Status
291==============
292
293AddressSanitizer is fully functional on supported platforms starting from LLVM
2943.1. The test suite is integrated into CMake build and can be run with ``make
295check-asan`` command.
296
297More Information
298================
299
300`<https://github.com/google/sanitizers/wiki/AddressSanitizer>`_
301