159 lines
5.2 KiB
ReStructuredText
159 lines
5.2 KiB
ReStructuredText
|
================
|
||
|
AddressSanitizer
|
||
|
================
|
||
|
|
||
|
.. contents::
|
||
|
:local:
|
||
|
|
||
|
Introduction
|
||
|
============
|
||
|
|
||
|
AddressSanitizer is a fast memory error detector. It consists of a
|
||
|
compiler instrumentation module and a run-time library. The tool can
|
||
|
detect the following types of bugs:
|
||
|
|
||
|
- Out-of-bounds accesses to heap, stack and globals
|
||
|
- Use-after-free
|
||
|
- Use-after-return (to some extent)
|
||
|
- Double-free, invalid free
|
||
|
|
||
|
Typical slowdown introduced by AddressSanitizer is **2x**.
|
||
|
|
||
|
How to build
|
||
|
============
|
||
|
|
||
|
Follow the `clang build instructions <../get_started.html>`_. CMake
|
||
|
build is supported.
|
||
|
|
||
|
Usage
|
||
|
=====
|
||
|
|
||
|
Simply compile and link your program with ``-fsanitize=address`` flag.
|
||
|
The AddressSanitizer run-time library should be linked to the final
|
||
|
executable, so make sure to use ``clang`` (not ``ld``) for the final
|
||
|
link step.
|
||
|
When linking shared libraries, the AddressSanitizer run-time is not
|
||
|
linked, so ``-Wl,-z,defs`` may cause link errors (don't use it with
|
||
|
AddressSanitizer).
|
||
|
To get a reasonable performance add ``-O1`` or higher.
|
||
|
To get nicer stack traces in error messages add
|
||
|
``-fno-omit-frame-pointer``.
|
||
|
To get perfect stack traces you may need to disable inlining (just use
|
||
|
``-O1``) and tail call elimination (``-fno-optimize-sibling-calls``).
|
||
|
|
||
|
::
|
||
|
|
||
|
% cat example_UseAfterFree.cc
|
||
|
int main(int argc, char **argv) {
|
||
|
int *array = new int[100];
|
||
|
delete [] array;
|
||
|
return array[argc]; // BOOM
|
||
|
}
|
||
|
|
||
|
::
|
||
|
|
||
|
# Compile and link
|
||
|
% clang -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc
|
||
|
|
||
|
OR
|
||
|
|
||
|
::
|
||
|
|
||
|
# Compile
|
||
|
% clang -O1 -g -fsanitize=address -fno-omit-frame-pointer -c example_UseAfterFree.cc
|
||
|
# Link
|
||
|
% clang -g -fsanitize=address example_UseAfterFree.o
|
||
|
|
||
|
If a bug is detected, the program will print an error message to stderr
|
||
|
and exit with a non-zero exit code. Currently, AddressSanitizer does not
|
||
|
symbolize its output, so you may need to use a separate script to
|
||
|
symbolize the result offline (this will be fixed in future).
|
||
|
|
||
|
::
|
||
|
|
||
|
% ./a.out 2> log
|
||
|
% projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt
|
||
|
==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8
|
||
|
READ of size 4 at 0x7f7ddab8c084 thread T0
|
||
|
#0 0x403c8c in main example_UseAfterFree.cc:4
|
||
|
#1 0x7f7ddabcac4d in __libc_start_main ??:0
|
||
|
0x7f7ddab8c084 is located 4 bytes inside of 400-byte region [0x7f7ddab8c080,0x7f7ddab8c210)
|
||
|
freed by thread T0 here:
|
||
|
#0 0x404704 in operator delete[](void*) ??:0
|
||
|
#1 0x403c53 in main example_UseAfterFree.cc:4
|
||
|
#2 0x7f7ddabcac4d in __libc_start_main ??:0
|
||
|
previously allocated by thread T0 here:
|
||
|
#0 0x404544 in operator new[](unsigned long) ??:0
|
||
|
#1 0x403c43 in main example_UseAfterFree.cc:2
|
||
|
#2 0x7f7ddabcac4d in __libc_start_main ??:0
|
||
|
==9442== ABORTING
|
||
|
|
||
|
AddressSanitizer exits on the first detected error. This is by design.
|
||
|
One reason: it makes the generated code smaller and faster (both by
|
||
|
~5%). Another reason: this makes fixing bugs unavoidable. With Valgrind,
|
||
|
it is often the case that users treat Valgrind warnings as false
|
||
|
positives (which they are not) and don't fix them.
|
||
|
|
||
|
\_\_has\_feature(address\_sanitizer)
|
||
|
------------------------------------
|
||
|
|
||
|
In some cases one may need to execute different code depending on
|
||
|
whether AddressSanitizer is enabled.
|
||
|
`\_\_has\_feature <LanguageExtensions.html#__has_feature_extension>`_
|
||
|
can be used for this purpose.
|
||
|
|
||
|
::
|
||
|
|
||
|
#if defined(__has_feature)
|
||
|
# if __has_feature(address_sanitizer)
|
||
|
code that builds only under AddressSanitizer
|
||
|
# endif
|
||
|
#endif
|
||
|
|
||
|
``__attribute__((no_address_safety_analysis))``
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
Some code should not be instrumented by AddressSanitizer. One may use
|
||
|
the function attribute
|
||
|
`no_address_safety_analysis <LanguageExtensions.html#address_sanitizer>`_
|
||
|
to disable instrumentation of a particular function. This attribute may
|
||
|
not be supported by other compilers, so we suggest to use it together
|
||
|
with ``__has_feature(address_sanitizer)``. Note: currently, this
|
||
|
attribute will be lost if the function is inlined.
|
||
|
|
||
|
Supported Platforms
|
||
|
===================
|
||
|
|
||
|
AddressSanitizer is supported on
|
||
|
|
||
|
- Linux i386/x86\_64 (tested on Ubuntu 10.04 and 12.04).
|
||
|
- MacOS 10.6, 10.7 and 10.8 (i386/x86\_64).
|
||
|
|
||
|
Support for Linux ARM (and Android ARM) is in progress (it may work, but
|
||
|
is not guaranteed too).
|
||
|
|
||
|
Limitations
|
||
|
===========
|
||
|
|
||
|
- AddressSanitizer uses more real memory than a native run. Exact
|
||
|
overhead depends on the allocations sizes. The smaller the
|
||
|
allocations you make the bigger the overhead is.
|
||
|
- AddressSanitizer uses more stack memory. We have seen up to 3x
|
||
|
increase.
|
||
|
- On 64-bit platforms AddressSanitizer maps (but not reserves) 16+
|
||
|
Terabytes of virtual address space. This means that tools like
|
||
|
``ulimit`` may not work as usually expected.
|
||
|
- Static linking is not supported.
|
||
|
|
||
|
Current Status
|
||
|
==============
|
||
|
|
||
|
AddressSanitizer is fully functional on supported platforms starting
|
||
|
from LLVM 3.1. The test suite is integrated into CMake build and can be
|
||
|
run with ``make check-asan`` command.
|
||
|
|
||
|
More Information
|
||
|
================
|
||
|
|
||
|
`http://code.google.com/p/address-sanitizer <http://code.google.com/p/address-sanitizer/>`_.
|