blob: 8935dbacf60d37e66fbd5fd5032f7bd28c226677 [file] [log] [blame] [view]
Staphany Park384b99a2019-12-18 03:23:341# AddressSanitizer (ASan)
2
3[AddressSanitizer](https://github.com/google/sanitizers) (ASan) is a fast memory
4error detector based on compiler instrumentation (LLVM). It is fully usable for
Nico Weber3b6c2552020-09-09 19:49:455Chrome on Android, Chrome OS, iOS simulator, Linux, Mac, and 64-bit Windows.
6Additional info on the tool itself is available at
Darwin Huang7d3b5f052019-12-23 19:25:527https://clang.llvm.org/docs/AddressSanitizer.html.
Staphany Park384b99a2019-12-18 03:23:348
9For the memory leak detector built into ASan, see
10[LeakSanitizer](https://sites.google.com/a/chromium.org/dev/developers/testing/leaksanitizer).
11If you want to debug memory leaks, please refer to the instructions on that page
12instead.
13
14## Buildbots and trybots
15
16The [Chromium Memory
Nico Weber3b6c2552020-09-09 19:49:4517waterfall](https://ci.chromium.org/p/chromium/g/chromium.memory/console)
18contains buildbots running Chromium tests under ASan on Linux (Linux ASan/LSan
19bots for the regular Linux build, Linux Chromium OS ASan for the chromeos=1
20build running on Linux), macOS, Chromium OS. Linux and Linux Chromium OS bots
21run with --no-sandbox, but there's an extra Linux bot that enables the sandbox
22(but disables LeakSanitizer).
Staphany Park384b99a2019-12-18 03:23:3423
Darwin Huang7d3b5f052019-12-23 19:25:5224The trybots running Chromium tests on Linux and macOS are:
Nico Weber3b6c2552020-09-09 19:49:4525- linux\_asan (everything except browser\_tests and content\_browsertests)
26- linux\_browser\_asan (browser\_tests and content\_browsertests),
27- mac\_asan (many tests including browser\_tests and content\_browsertests)
28- linux\_chromeos\_asan (the chromeos=1 build running on a Linux machine, many
29tests including browser\_tests and content\_browsertests).
Staphany Park384b99a2019-12-18 03:23:3430
31## Pre-built Chrome binaries
32
33You can grab fresh Chrome binaries built with ASan
34[here](https://commondatastorage.googleapis.com/chromium-browser-asan/index.html).
Chris Thompson4c93a6e2020-12-17 02:20:5135The lists of ASan binaries are _very_ long, but you can filter down to more
36specific releases by specifying a prefix like
37[linux-debug/asan-linux-debug-83](https://commondatastorage.googleapis.com/chromium-browser-asan/index.html?prefix=linux-debug/asan-linux-debug-83).
38This is useful for finding a build for a specific revision, since filenames are of
39the form `asan-<platform>-<buildtype>-<revision>` (but not every revision has an
40archived ASan build).
Staphany Park384b99a2019-12-18 03:23:3441
42## Build tests with ASan
43
Nico Weber3b6c2552020-09-09 19:49:4544Building with ASan is easy. Start by compiling `base_unittests` to verify the
45build is working for you (see below). Then, you can compile `chrome`,
46`browser_tests`, etc.. Make sure to compile release builds.
Staphany Park384b99a2019-12-18 03:23:3447
48### Configuring the build
49
50Create an asan build directory by running:
Darwin Huang7d3b5f052019-12-23 19:25:5251```shell
Staphany Park384b99a2019-12-18 03:23:3452gn args out/asan
53```
54
55Enter the following build variables in the editor that will pop up:
Darwin Huang7d3b5f052019-12-23 19:25:5256```python
Staphany Park384b99a2019-12-18 03:23:3457is_asan = true
58is_debug = false # Release build.
59```
60
61Build with:
Darwin Huang7d3b5f052019-12-23 19:25:5262```shell
Staphany Park384b99a2019-12-18 03:23:3463ninja -C out/asan base_unittests
64```
65
66### Goma build
67
Nico Weber3b6c2552020-09-09 19:49:4568ASan builds should work seamlessly with Goma; just add `use_goma=true` in your
69"gn args" Don't forget to use `ninja -j <jobs>` to take advantage of goma.
Staphany Park384b99a2019-12-18 03:23:3470
71### Build options
72
73If you want your stack traces to be precise, you will have to disable inlining
74by setting the GN arg:
Darwin Huang7d3b5f052019-12-23 19:25:5275```shell
Staphany Park384b99a2019-12-18 03:23:3476enable_full_stack_frames_for_profiling = true
77```
78
79Note that this incurs a significant performance hit. Please do not do this on
80buildbots.
81
82If you're working on reproducing ClusterFuzz reports, you might want to add:
Darwin Huang7d3b5f052019-12-23 19:25:5283```shell
Staphany Park384b99a2019-12-18 03:23:3484v8_enable_verify_heap = true
85```
Darwin Huang7d3b5f052019-12-23 19:25:5286in order to enable the `--verify-heap` command line flag for v8 in Release builds.
Staphany Park384b99a2019-12-18 03:23:3487
88## Verify the ASan tool works
89
90**ATTENTION (Linux only)**: These instructions are for running ASan in a way
91that is compatible with the sandbox. However, this is not compatible with
92LeakSanitizer. If you want to debug memory leaks, please use the instructions on
93the
94[LeakSanitizer](https://sites.google.com/a/chromium.org/dev/developers/testing/leaksanitizer)
95page instead.
96
97Now, check that the tool works. Run the following:
Darwin Huang7d3b5f052019-12-23 19:25:5298```shell
99out/asan/base_unittests \
100 --gtest_filter=ToolsSanityTest.DISABLED_AddressSanitizerLocalOOBCrashTest \
Amy Huangaaa8dcb2021-03-16 18:54:34101 --gtest_also_run_disabled_tests
Staphany Park384b99a2019-12-18 03:23:34102```
103
104The test will crash with the following error report:
Darwin Huang7d3b5f052019-12-23 19:25:52105```shell
106==26552== ERROR: AddressSanitizer stack-buffer-overflow on address \
1070x7fff338adb14 at pc 0xac20a7 bp 0x7fff338adad0 sp 0x7fff338adac8
Staphany Park384b99a2019-12-18 03:23:34108WRITE of size 4 at 0x7fff338adb14 thread T0
109 #0 0xac20a7 in base::ToolsSanityTest_DISABLED_AddressSanitizerLocalOOBCrashTest_Test::TestBody() ???:0
110 #1 0xcddbd6 in testing::Test::Run() testing/gtest/src/gtest.cc:2161
111 #2 0xcdf63b in testing::TestInfo::Run() testing/gtest/src/gtest.cc:2338
112... lots more stuff
Darwin Huang7d3b5f052019-12-23 19:25:52113Address 0x7fff338adb14 is located at offset 52 in frame \
114base::ToolsSanityTest_DISABLED_AddressSanitizerLocalOOBCrashTest_Test::TestBody()> of T0's stack:
Staphany Park384b99a2019-12-18 03:23:34115 This frame has 2 object(s):
116 [32, 52) 'array'
117 [96, 104) 'access'
118==26552== ABORTING
119... lots more stuff
120```
121
Samuel Huange9a7bff9d2020-03-04 16:16:03122Congrats, you have a working ASan build! &#x1F64C;
Staphany Park384b99a2019-12-18 03:23:34123
124## Run chrome under ASan
125
Darwin Huang7d3b5f052019-12-23 19:25:52126And finally, have fun with the `out/Release/chrome` binary. The filter script
Amy Huangaaa8dcb2021-03-16 18:54:34127`tools/valgrind/asan/asan_symbolize.py` can be used to symbolize the output,
128although it shouldn't be necessary on Linux and Windows, where Chrome uses the
129llvm-symbolizer in its source tree by default.
Staphany Park384b99a2019-12-18 03:23:34130
131ASan should perfectly work with Chrome's sandbox. You should only need to run
132with `--no-sandbox` on Linux if you're debugging ASan.
133Note: you have to disable the sandbox on Windows until it is supported.
134
135You may need to run with `--disable-gpu` on Linux with NVIDIA driver older than
136295.20.
137
138You will likely need to define environment variable
139[`G_SLICE=always-malloc`](https://developer.gnome.org/glib/unstable/glib-running.html)
140to avoid crashes inside gtk.
Nico Weber3b6c2552020-09-09 19:49:45141`NSS_DISABLE_ARENA_FREE_LIST=1` and `NSS_DISABLE_UNLOAD=1` are required as well.
Staphany Park384b99a2019-12-18 03:23:34142
143When filing a bug found by AddressSanitizer, please add a label
144`Stability-AddressSanitizer`.
145
146## ASan runtime options
147
148ASan's behavior can be changed by exporting the `ASAN_OPTIONS` env var. Some of
149the useful options are listed on this page, others can be obtained from running
150an ASanified binary with `ASAN_OPTIONS=help=1`. Note that Chromium sets its own
151defaults for some options, so the default behavior may be different from that
152observed in other projects.
Michael Lippautz9236a2c2021-07-22 21:53:19153See `build/sanitizers/sanitizer_options.cc` for more details.
Staphany Park384b99a2019-12-18 03:23:34154
155## NaCl support under ASan
156
Nico Weber3b6c2552020-09-09 19:49:45157On Linux (and soon on macOS) you can build and run Chromium with NaCl under ASan.
Staphany Park384b99a2019-12-18 03:23:34158Untrusted code (nexe) itself is not instrumented with ASan in this mode, but
159everything else is.
160
Nico Weber3b6c2552020-09-09 19:49:45161To do this, remove `enable_nacl=false` from your `args.gn`, and define
Staphany Park384b99a2019-12-18 03:23:34162`NACL_DANGEROUS_SKIP_QUALIFICATION_TEST=1` in your environment at run time.
163
164Pipe chromium output (stderr) through ``tools/valgrind/asan/asan_symbolize.py
165`pwd`/`` to get function names and line numbers in ASan reports.
Darwin Huang7d3b5f052019-12-23 19:25:52166If you're seeing crashes within `nacl_helper_bootstrap`, try deleting
167`out/Release/nacl_helper`.
Staphany Park384b99a2019-12-18 03:23:34168
169## Building on iOS
170
171It's possible to build and run Chrome tests for iOS simulator (which are x86
172binaries essentially) under ASan. Note that you'll need a Chrome iOS checkout
173for that. It isn't currently possible to build iOS binaries targeting ARM.
174
175Configure your build with `is_asan = true` as described above. Replace your
176build directory as needed:
Darwin Huang7d3b5f052019-12-23 19:25:52177```shell
Staphany Park384b99a2019-12-18 03:23:34178ninja -C out/Release-iphonesimulator base_unittests
Darwin Huang7d3b5f052019-12-23 19:25:52179out/Release-iphonesimulator/iossim -d "iPhone" -s 7.0 \
180 out/Release-iphonesimulator/base_unittests.app/ \
181 --gtest_filter=ToolsSanityTest.DISABLED_AddressSanitizerLocalOOBCrashTest \
182 --gtest_also_run_disabled_tests 2>&1 |
Staphany Park384b99a2019-12-18 03:23:34183tools/valgrind/asan/asan_symbolize.py
184```
185
186You'll see the same report as shown above (see the "Verify the ASan tool works"
187section), with a number of iOS-specific frames.
188
189## Building on Android
190
191Follow [AndroidBuildInstructions](android_build_instructions.md) with minor
192changes:
193
Darwin Huang7d3b5f052019-12-23 19:25:52194```python
195target_os="android"
Darwin Huang7d3b5f052019-12-23 19:25:52196is_asan=true
197is_debug=false
198```
Staphany Park384b99a2019-12-18 03:23:34199
200Running ASan applications on Android requires additional device setup. Chromium
201testing scripts take care of this, so testing works as expected:
Darwin Huang7d3b5f052019-12-23 19:25:52202```shell
203build/android/test_runner.py instrumentation --test-apk ContentShellTest \
204 --test_data content:content/test/data/android/device_files -v -v -v \
205 --tool=asan --release
Staphany Park384b99a2019-12-18 03:23:34206```
207
Hazem Ashmawy382171a2021-06-29 22:05:32208If the above step fails or to run stuff without Chromium testing script (ex.
209ContentShell.apk, or any third party apk or binary), device setup is needed:
Darwin Huang7d3b5f052019-12-23 19:25:52210```shell
Samuel Huange9a7bff9d2020-03-04 16:16:03211tools/android/asan/third_party/asan_device_setup.sh \
212 --lib third_party/llvm-build/Release+Asserts/lib/clang/*/lib/linux/libclang_rt.asan-arm-android.so
Staphany Park384b99a2019-12-18 03:23:34213# wait a few seconds for the device to reload
214```
Hazem Ashmawy382171a2021-06-29 22:05:32215**Note:** You need to replace `-arm-` part in `libclang_rt.asan-arm-android.so`
216in the command above with the corresponding architecture of the android device
217(e.g `-i686-` if you are running an `x86` emulator image).
Staphany Park384b99a2019-12-18 03:23:34218
219It only needs to be run once per device. It is safe to run it multiple times.
Samuel Huange9a7bff9d2020-03-04 16:16:03220Examine the output to ensure that setup was successful (you may need to run
221`adb disable-verity` and restart the device first). When this is done, the
222device will run ASan apks as well as normal apks without any further setup.
Staphany Park384b99a2019-12-18 03:23:34223
224To run command-line tools (i.e. binaries), prefix them with `asanwrapper`:
Darwin Huang7d3b5f052019-12-23 19:25:52225```shell
Staphany Park384b99a2019-12-18 03:23:34226adb shell /system/bin/asanwrapper /path/to/binary
227```
228
Darwin Huang7d3b5f052019-12-23 19:25:52229Use `build/android/asan_symbolize.py` to symbolize stack from `adb logcat`. It
230needs the `--output-directory` argument and takes care of translating the device
231path to the unstripped binary in the output directory.
Staphany Park384b99a2019-12-18 03:23:34232
Nico Weber3b6c2552020-09-09 19:49:45233## Building with v8\_target\_arch="arm"
Staphany Park384b99a2019-12-18 03:23:34234
235This is needed to detect addressability bugs in the ARM code emitted by V8 and
236running on an instrumented ARM emulator in a 32-bit x86 Linux Chromium. **You
237probably don't want this, and these instructions have bitrotted because they
238still reference GYP. If you do this successfully, please update!** See
Darwin Huang7d3b5f052019-12-23 19:25:52239https://crbug.com/324207 for some context.
Staphany Park384b99a2019-12-18 03:23:34240
241First, you need to install the 32-bit chroot environment using the
242`build/install-chroot.sh` script (as described in
243https://code.google.com/p/chromium/wiki/LinuxBuild32On64). Second, install the
244build deps:
Darwin Huang7d3b5f052019-12-23 19:25:52245```shell
246precise32 build/install-build-deps.sh \
247 # assuming your schroot wrapper is called 'precise32'
Staphany Park384b99a2019-12-18 03:23:34248```
249
250You'll need to make two symlinks to avoid linking errors:
Darwin Huang7d3b5f052019-12-23 19:25:52251```shell
252sudo ln -s $CHROOT/usr/lib/i386-linux-gnu/libc_nonshared.a \
253 /usr/lib/i386-linux-gnu/libc_nonshared.a
254sudo ln -s $CHROOT/usr/lib/i386-linux-gnu/libpthread_nonshared.a \
255 /usr/lib/i386-linux-gnu/libpthread_nonshared.a
Staphany Park384b99a2019-12-18 03:23:34256```
257
258Now configure and build your Chrome:
Darwin Huang7d3b5f052019-12-23 19:25:52259```shell
260GYP_GENERATOR_FLAGS="output_dir=out_asan_chroot" GYP_DEFINES="asan=1 \
261 disable_nacl=1 v8_target_arch=arm sysroot=/var/lib/chroot/precise32bit/ \
262 chroot_cmd=precise32 host_arch=x86_64 target_arch=ia32" gclient runhooks
Staphany Park384b99a2019-12-18 03:23:34263ninja -C out_asan_chroot/Release chrome
264```
265
266**Note**: `disable_nacl=1` is needed for now.
267
James Cook0c3837bc2021-08-12 01:30:36268## Running on Chrome OS
269
270For the linux-chromeos "emulator" build, run Asan following the instructions
271above, just like you would for Linux.
272
273For Chromebook hardware, add `is_asan = true` to your args.gn and build.
274`deploy_chrome` with `--mount` and `--nostrip`. ASan logs can be found in
275`/var/log/asan/`.
276
277To catch crashes in gdb:
278
279- Edit `/etc/chrome_dev.conf` and add `ASAN_OPTIONS=abort_on_error=1`
280- `restart ui`
281- gdb -p 12345 # Find the pid from /var/log/chrome/chrome
282
283When you trigger the crash, you'll get a SIGABRT in gdb. `bt` will show the
284stack.
285
286See
287[Chrome OS stack traces](https://chromium.googlesource.com/chromiumos/docs/+/main/stack_traces.md)
288for more details.
289
Staphany Park384b99a2019-12-18 03:23:34290## AsanCoverage
291
292AsanCoverage is a minimalistic code coverage implementation built into ASan. For
293general information see
294[https://code.google.com/p/address-sanitizer/wiki/AsanCoverage](https://github.com/google/sanitizers)
295To use AsanCoverage in Chromium, add `use_sanitizer_coverage = true` to your GN
296args. See also the `sanitizer_coverage_flags` variable for configuring it.
297
298Chrome must be terminated gracefully in order for coverage to work. Either close
299the browser, or SIGTERM the browser process. Do not do `killall chrome` or send
300SIGKILL.
Darwin Huang7d3b5f052019-12-23 19:25:52301```shell
302kill <browser_process_pid>
303ls
Staphany Park384b99a2019-12-18 03:23:34304...
305chrome.22575.sancov
306gpu.6916123572022919124.sancov.packed
307zygote.13651804083035800069.sancov.packed
308...
309```
310
311The `gpu.*.sancov.packed` file contains coverage data for the GPU process,
312whereas the `zygote.*.sancov.packed` file contains coverage data for the
313renderers (but not the zygote process). Unpack them to regular `.sancov` files
314like so:
Darwin Huang7d3b5f052019-12-23 19:25:52315```shell
316$ $LLVM/projects/compiler-rt/lib/sanitizer_common/scripts/sancov.py unpack \
317 *.sancov.packed
Staphany Park384b99a2019-12-18 03:23:34318sancov.py: unpacking gpu.6916123572022919124.sancov.packed
319sancov.py: extracting chrome.22610.sancov
320sancov.py: unpacking zygote.13651804083035800069.sancov.packed
321sancov.py: extracting libpdf.so.12.sancov
322sancov.py: extracting chrome.12.sancov
323sancov.py: extracting libpdf.so.10.sancov
324sancov.py: extracting chrome.10.sancov
325```
326
327Now, e.g., to list the offsets of covered functions in the libpdf.so binary in
328renderer with pid 10:
Darwin Huang7d3b5f052019-12-23 19:25:52329```shell
330$ $LLVM/projects/compiler-rt/lib/sanitizer_common/scripts/sancov.py print \
331 libpdf.so.10.sancov
Staphany Park384b99a2019-12-18 03:23:34332```