Sean Silva | 93ca021 | 2012-12-13 01:10:46 +0000 | [diff] [blame^] | 1 | ================ |
| 2 | AddressSanitizer |
| 3 | ================ |
| 4 | |
| 5 | .. contents:: |
| 6 | :local: |
| 7 | |
| 8 | Introduction |
| 9 | ============ |
| 10 | |
| 11 | AddressSanitizer is a fast memory error detector. It consists of a |
| 12 | compiler instrumentation module and a run-time library. The tool can |
| 13 | detect the following types of bugs: |
| 14 | |
| 15 | - Out-of-bounds accesses to heap, stack and globals |
| 16 | - Use-after-free |
| 17 | - Use-after-return (to some extent) |
| 18 | - Double-free, invalid free |
| 19 | |
| 20 | Typical slowdown introduced by AddressSanitizer is **2x**. |
| 21 | |
| 22 | How to build |
| 23 | ============ |
| 24 | |
| 25 | Follow the `clang build instructions <../get_started.html>`_. CMake |
| 26 | build is supported. |
| 27 | |
| 28 | Usage |
| 29 | ===== |
| 30 | |
| 31 | Simply compile and link your program with ``-fsanitize=address`` flag. |
| 32 | The AddressSanitizer run-time library should be linked to the final |
| 33 | executable, so make sure to use ``clang`` (not ``ld``) for the final |
| 34 | link step. |
| 35 | When linking shared libraries, the AddressSanitizer run-time is not |
| 36 | linked, so ``-Wl,-z,defs`` may cause link errors (don't use it with |
| 37 | AddressSanitizer). |
| 38 | To get a reasonable performance add ``-O1`` or higher. |
| 39 | To get nicer stack traces in error messages add |
| 40 | ``-fno-omit-frame-pointer``. |
| 41 | To get perfect stack traces you may need to disable inlining (just use |
| 42 | ``-O1``) and tail call elimination (``-fno-optimize-sibling-calls``). |
| 43 | |
| 44 | :: |
| 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 | :: |
| 54 | |
| 55 | # Compile and link |
| 56 | % clang -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc |
| 57 | |
| 58 | OR |
| 59 | |
| 60 | :: |
| 61 | |
| 62 | # Compile |
| 63 | % clang -O1 -g -fsanitize=address -fno-omit-frame-pointer -c example_UseAfterFree.cc |
| 64 | # Link |
| 65 | % clang -g -fsanitize=address example_UseAfterFree.o |
| 66 | |
| 67 | If a bug is detected, the program will print an error message to stderr |
| 68 | and exit with a non-zero exit code. Currently, AddressSanitizer does not |
| 69 | symbolize its output, so you may need to use a separate script to |
| 70 | symbolize the result offline (this will be fixed in future). |
| 71 | |
| 72 | :: |
| 73 | |
| 74 | % ./a.out 2> log |
| 75 | % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt |
| 76 | ==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8 |
| 77 | READ of size 4 at 0x7f7ddab8c084 thread T0 |
| 78 | #0 0x403c8c in main example_UseAfterFree.cc:4 |
| 79 | #1 0x7f7ddabcac4d in __libc_start_main ??:0 |
| 80 | 0x7f7ddab8c084 is located 4 bytes inside of 400-byte region [0x7f7ddab8c080,0x7f7ddab8c210) |
| 81 | freed by thread T0 here: |
| 82 | #0 0x404704 in operator delete[](void*) ??:0 |
| 83 | #1 0x403c53 in main example_UseAfterFree.cc:4 |
| 84 | #2 0x7f7ddabcac4d in __libc_start_main ??:0 |
| 85 | previously allocated by thread T0 here: |
| 86 | #0 0x404544 in operator new[](unsigned long) ??:0 |
| 87 | #1 0x403c43 in main example_UseAfterFree.cc:2 |
| 88 | #2 0x7f7ddabcac4d in __libc_start_main ??:0 |
| 89 | ==9442== ABORTING |
| 90 | |
| 91 | AddressSanitizer exits on the first detected error. This is by design. |
| 92 | One reason: it makes the generated code smaller and faster (both by |
| 93 | ~5%). Another reason: this makes fixing bugs unavoidable. With Valgrind, |
| 94 | it is often the case that users treat Valgrind warnings as false |
| 95 | positives (which they are not) and don't fix them. |
| 96 | |
| 97 | \_\_has\_feature(address\_sanitizer) |
| 98 | ------------------------------------ |
| 99 | |
| 100 | In some cases one may need to execute different code depending on |
| 101 | whether AddressSanitizer is enabled. |
| 102 | `\_\_has\_feature <LanguageExtensions.html#__has_feature_extension>`_ |
| 103 | can be used for this purpose. |
| 104 | |
| 105 | :: |
| 106 | |
| 107 | #if defined(__has_feature) |
| 108 | # if __has_feature(address_sanitizer) |
| 109 | code that builds only under AddressSanitizer |
| 110 | # endif |
| 111 | #endif |
| 112 | |
| 113 | ``__attribute__((no_address_safety_analysis))`` |
| 114 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 115 | |
| 116 | Some code should not be instrumented by AddressSanitizer. One may use |
| 117 | the function attribute |
| 118 | `no_address_safety_analysis <LanguageExtensions.html#address_sanitizer>`_ |
| 119 | to disable instrumentation of a particular function. This attribute may |
| 120 | not be supported by other compilers, so we suggest to use it together |
| 121 | with ``__has_feature(address_sanitizer)``. Note: currently, this |
| 122 | attribute will be lost if the function is inlined. |
| 123 | |
| 124 | Supported Platforms |
| 125 | =================== |
| 126 | |
| 127 | AddressSanitizer is supported on |
| 128 | |
| 129 | - Linux i386/x86\_64 (tested on Ubuntu 10.04 and 12.04). |
| 130 | - MacOS 10.6, 10.7 and 10.8 (i386/x86\_64). |
| 131 | |
| 132 | Support for Linux ARM (and Android ARM) is in progress (it may work, but |
| 133 | is not guaranteed too). |
| 134 | |
| 135 | Limitations |
| 136 | =========== |
| 137 | |
| 138 | - AddressSanitizer uses more real memory than a native run. Exact |
| 139 | overhead depends on the allocations sizes. The smaller the |
| 140 | allocations you make the bigger the overhead is. |
| 141 | - AddressSanitizer uses more stack memory. We have seen up to 3x |
| 142 | increase. |
| 143 | - On 64-bit platforms AddressSanitizer maps (but not reserves) 16+ |
| 144 | Terabytes of virtual address space. This means that tools like |
| 145 | ``ulimit`` may not work as usually expected. |
| 146 | - Static linking is not supported. |
| 147 | |
| 148 | Current Status |
| 149 | ============== |
| 150 | |
| 151 | AddressSanitizer is fully functional on supported platforms starting |
| 152 | from LLVM 3.1. The test suite is integrated into CMake build and can be |
| 153 | run with ``make check-asan`` command. |
| 154 | |
| 155 | More Information |
| 156 | ================ |
| 157 | |
| 158 | `http://code.google.com/p/address-sanitizer <http://code.google.com/p/address-sanitizer/>`_. |