1 page.title=AddressSanitizer 2 @jd:body 3 4 <!-- 5 Copyright 2015 The Android Open Source Project 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 --> 19 <div id="qv-wrapper"> 20 <div id="qv"> 21 <h2>In this document</h2> 22 <ol id="auto-toc"> 23 </ol> 24 </div> 25 </div> 26 27 <h2 id=purpose>Purpose</h2> 28 29 <p>AddressSanitizer (ASan) is a fast compiler-based tool for detecting memory bugs 30 in native code. It is comparable to Valgrind (Memcheck tool), but, unlike it, 31 ASan:</p> 32 33 <ul> 34 <li> + detects overflows on stack and global objects 35 <li> - does not detect uninitialized reads and memory leaks 36 <li> + is much faster (two-three times slowdown compared to Valgrinds 20-100x) 37 <li> + has less memory overhead 38 </ul> 39 40 <p>This document describes how to build and run parts of the Android platform with 41 AddressSanitizer. If you are looking to build a standalone (i.e. SDK/NDK) 42 application with AddressSanitizer, see the <a 43 href="https://github.com/google/sanitizers/wiki/AddressSanitizerOnAndroid">AddressSanitizerOnAndroid</a> 44 public project site instead.</p> 45 46 <p>AddressSanitizer consists of a compiler (<code>external/clang</code>) and a runtime library 47 (<code>external/compiler-rt/lib/asan</code>).</p> 48 49 <p class="note"><strong>Note</strong>: Use the current master 50 branch to gain access to the <a href="#sanitize_target">SANITIZE_TARGET</a> 51 feature and the ability to build the entire Android platform with 52 AddressSanitizer at once. Otherwise, you are limited to using 53 <code>LOCAL_SANITIZE</code>.</p> 54 55 <h2 id=building_with_clang>Building with Clang</h2> 56 57 <p>As a first step to building an ASan-instrumented binary, make sure that your 58 code builds with Clang. This is done by adding <code>LOCAL_CLANG:=true</code> 59 to the build rules. Clang may find bugs in your code that GCC missed.</p> 60 61 <h2 id=building_executables_with_addresssanitizer>Building executables with AddressSanitizer</h2> 62 63 <p>Add <code>LOCAL_SANITIZE:=address</code> to the build rule of the 64 executable. This requires: <code>LOCAL_CLANG:=true</code></p> 65 66 <pre> 67 LOCAL_CLANG:=true 68 LOCAL_SANITIZE:=address 69 </pre> 70 71 <p>When a bug is detected, ASan prints a verbose report both to the standard 72 output and to <code>logcat</code> and then crashes the process.</p> 73 74 <h2 id=building_shared_libraries_with_addresssanitizer>Building shared libraries with AddressSanitizer</h2> 75 76 <p>Due to the way ASan works, a library built with ASan cannot be used by an 77 executable that's built without ASan.</p> 78 79 <p class="note">Note</strong>: In runtime situations where an ASan library is 80 loaded into an incorrect process, you will see unresolved symbol messages 81 starting with <code>_asan</code> or <code>_sanitizer</code>.</p> 82 83 <p>To sanitize a shared library that is used in multiple executables, not all of 84 which are built with ASan, you'll need two copies of the library. The 85 recommended way to do this is to add the following to <code>Android.mk</code> 86 for the module in question:</p> 87 88 <pre> 89 LOCAL_CLANG:=true 90 LOCAL_SANITIZE:=address 91 LOCAL_MODULE_RELATIVE_PATH := asan 92 </pre> 93 94 <p>This puts the library in <code>/system/lib/asan</code> instead of 95 <code>/system/lib</code>. Then, run your executable with: 96 <code>LD_LIBRARY_PATH=/system/lib/asan</code></p> 97 98 <p>For system daemons, add the following to the appropriate section of 99 <code>/init.rc</code> or <code>/init.$device$.rc</code>.</p> 100 101 <pre> 102 setenv LD_LIBRARY_PATH /system/lib/asan 103 </pre> 104 105 <p class="warning"><strong>Warning</strong>: The <code>LOCAL_MODULE_RELATIVE_PATH</code> 106 setting <strong>moves</strong> your library to <code>/system/lib/asan</code>, 107 meaning that clobbering and rebuilding from scratch will result in the 108 library missing from <code>/system/lib</code>, and probably an unbootable 109 image. That's an unfortunate limitation of the 110 current build system. Don't clobber; do <code>make -j $N</code> and <code>adb 111 sync</code>.</p> 112 113 <p>Verify the process is using libraries from <code>/system/lib/asan</code> 114 when present by reading <code>/proc/$PID/maps</code>. If it's not, you may need 115 to disable SELinux, like so:</p> 116 117 <pre> 118 $ adb root 119 $ adb shell setenforce 0 120 # restart the process with adb shell kill $PID 121 # if it is a system service, or may be adb shell stop; adb shell start. 122 </pre> 123 124 <h2 id=better_stack_traces>Better stack traces</h2> 125 126 <p>AddressSanitizer uses a fast, frame-pointer-based unwinder to record a stack 127 trace for every memory allocation and deallocation event in the program. Most 128 of Android is built without frame pointers. As a result, you will often get 129 only one or two meaningful frames. To fix this, either rebuild the library with 130 ASan (recommended!), or with:</p> 131 132 <pre> 133 LOCAL_CFLAGS:=-fno-omit-frame-pointer 134 LOCAL_ARM_MODE:=arm 135 </pre> 136 137 <p>Or set <code>ASAN_OPTIONS=fast_unwind_on_malloc=0</code> in the process 138 environment. The latter can be very CPU-intensive, depending on 139 the load.</p> 140 141 <h2 id=symbolization>Symbolization</h2> 142 143 <p>Initially, ASan reports contain references to offsets in binaries and shared 144 libraries. There are two ways to obtain source file and line information:</p> 145 146 <ul> 147 <li>Ensure llvm-symbolizer binary is present in <code>/system/bin</code>. 148 Llvm-symbolizer is built from sources in: 149 <code>third_party/llvm/tools/llvm-symbolizer</code> <li>Filter the report 150 through the <code>external/compiler-rt/lib/asan/scripts/symbolize.py</code> 151 script. 152 </ul> 153 154 <p>The second approach can provide more data (i.e. file:line locations) because of 155 the availability of symbolized libraries on the host.</p> 156 157 <h2 id=addresssanitizer_in_the_apps>AddressSanitizer in the apps</h2> 158 159 <p>AddressSanitizer cannot see into Java code, but it can detect bugs in the JNI 160 libraries. For that, you'll need to build the executable with ASan, which in 161 this case is <code>/system/bin/app_process(<em>32|64</code></em>). This will 162 enable ASan in all apps on the device at the same time, which is a 163 bit stressful, but nothing that a 2GB RAM device cannot handle.</p> 164 165 <p>Add the usual <code>LOCAL_CLANG:=true, LOCAL_SANITIZE:=address</code> to 166 the app_process build rule in <code>frameworks/base/cmds/app_process</code>. Ignore 167 the <code>app_process__asan</code> target in the same file for now (if it is 168 still there at the time you read 169 this). Edit the Zygote record in 170 <code>system/core/rootdir/init.zygote(<em>32|64</em>).rc</code> to add the 171 following lines:</p> 172 173 <pre> 174 setenv LD_LIBRARY_PATH /system/lib/asan:/system/lib 175 setenv ASAN_OPTIONS 176 allow_user_segv_handler=true 177 </pre> 178 179 <p>Build, adb sync, fastboot flash boot, reboot.</p> 180 181 <h2 id=using_the_wrap_property>Using the wrap property</h2> 182 183 <p>The approach in the previous section puts AddressSanitizer into every 184 application in the system (actually, into every descendant of the Zygote 185 process). It is possible to run only one (or several) applications with ASan, 186 trading some memory overhead for slower application startup.</p> 187 188 <p>This can be done by starting your app with the wrap. property, the same one 189 thats used to run apps under Valgrind. The following example runs the Gmail app 190 under ASan:</p> 191 192 <pre> 193 $ adb root 194 $ adb shell setenforce 0 # disable SELinux 195 $ adb shell setprop wrap.com.google.android.gm "asanwrapper" 196 </pre> 197 198 <p>In this context, asanwrapper rewrites <code>/system/bin/app_process</code> 199 to <code>/system/bin/asan/app_process</code>, which is built with 200 AddressSanitizer. It also adds <code>/system/lib/asan</code> at the start of 201 the dynamic library search path. This way ASan-instrumented 202 libraries from <code>/system/lib/asan</code> are preferred to normal libraries 203 in <code>/system/lib</code> when running with asanwrapper.</p> 204 205 <p>Again, if a bug is found, the app will crash, and the report will be printed to 206 the log.</p> 207 208 <h2 id=sanitize_target>SANITIZE_TARGET</h2> 209 210 <p>The master branch has support for building the entire Android platform with 211 AddressSanitizer at once.</p> 212 213 <p>Run the following commands in the same build tree.</p> 214 215 <pre> 216 $ make -j42 217 $ make USE_CLANG_PLATFORM_BUILD:=true SANITIZE_TARGET=address -j42 218 </pre> 219 220 <p>In this mode, <code>userdata.img</code> contains extra libraries and must be 221 flashed to the device as well. Use the following command line:</p> 222 223 <pre> 224 $ fastboot flash userdata && fastboot flashall 225 </pre> 226 227 <p>At the moment of this writing, hammerhead-userdebug and shamu-userdebug boot to 228 the UI in this mode.</p> 229 230 <p>This works by building two sets of shared libraries: normal in 231 <code>/system/lib</code> (the first make invocation), ASan-instrumented in 232 <code>/data/lib</code> (the second make invocation). Executables from the 233 second build overwrite the ones from the first build. ASan-instrumented 234 executables get a different library search path that includes 235 <code>/data/lib</code> before <code>/system/lib</code> through the use of 236 "/system/bin/linker_asan" in PT_INTERP.</p> 237 238 <p>The build system clobbers intermediate object directories when the 239 <code>$SANITIZE_TARGET</code> value has changed. This forces a rebuild of all 240 targets while preserving installed binaries under <code>/system/lib</code>.</p> 241 242 <p>Some targets cannot be built with ASan:</p> 243 244 <ul> 245 <li>Statically linked executables. 246 <li><code>LOCAL_CLANG:=false</code> targets 247 <li><code>LOCAL_SANITIZE:=undefined</code>; will not be ASan'd for <code>SANITIZE_TARGET=address</code> 248 </ul> 249 250 <p>Executables like these are skipped in the SANITIZE_TARGET build, and the 251 version from the first make invocation is left in <code>/system/bin</code>.</p> 252 253 <p>Libraries like this are simply built without ASan. They can contain some ASan 254 code anyway from the static libraries they depend upon.</p> 255 256 <h2 id=supporting_documentation>Supporting documentation</h2> 257 258 <p><a href="https://github.com/google/sanitizers/wiki/AddressSanitizerOnAndroid">AddressSanitizerOnAndroid</a> public project site</p> 259 <p><a href="https://www.chromium.org/developers/testing/addresssanitizer">AddressSanitizer and Chromium</a></p> 260 <p><a href="https://github.com/google/sanitizers">Other Google Sanitizers</a></p> 261