blob: a5258c921281b72c3b90b34727a8fd331bca3fb5 [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
Solomon Kinarda2c503022024-06-14 18:08:1810[LeakSanitizer](https://www.chromium.org/developers/testing/leaksanitizer).
Staphany Park384b99a2019-12-18 03:23:3411If 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:
Lei Zhang2804210e2023-07-20 01:25:4225- linux\_chromium\_asan\_rel\_ng
26- mac\_chromium\_asan\_rel\_ng
27- linux\_chromium\_chromeos\_asan\_rel\_ng (the chromeos=1 build running on a
28Linux machine)
Staphany Park384b99a2019-12-18 03:23:3429
30## Pre-built Chrome binaries
31
32You can grab fresh Chrome binaries built with ASan
33[here](https://commondatastorage.googleapis.com/chromium-browser-asan/index.html).
Chris Thompson4c93a6e2020-12-17 02:20:5134The lists of ASan binaries are _very_ long, but you can filter down to more
35specific releases by specifying a prefix like
36[linux-debug/asan-linux-debug-83](https://commondatastorage.googleapis.com/chromium-browser-asan/index.html?prefix=linux-debug/asan-linux-debug-83).
37This is useful for finding a build for a specific revision, since filenames are of
38the form `asan-<platform>-<buildtype>-<revision>` (but not every revision has an
Chris Bookholtd30029202022-09-08 22:39:3139archived ASan build). The
40[get_asan_chrome](https://source.chromium.org/chromium/chromium/src/+/main:tools/get_asan_chrome/get_asan_chrome.py)
41helper script is a handy way to download builds; its --help flag provides
42usage instructions.
Staphany Park384b99a2019-12-18 03:23:3443
44## Build tests with ASan
45
Nico Weber3b6c2552020-09-09 19:49:4546Building with ASan is easy. Start by compiling `base_unittests` to verify the
47build is working for you (see below). Then, you can compile `chrome`,
48`browser_tests`, etc.. Make sure to compile release builds.
Staphany Park384b99a2019-12-18 03:23:3449
50### Configuring the build
51
52Create an asan build directory by running:
Darwin Huang7d3b5f052019-12-23 19:25:5253```shell
Staphany Park384b99a2019-12-18 03:23:3454gn args out/asan
55```
56
57Enter the following build variables in the editor that will pop up:
Darwin Huang7d3b5f052019-12-23 19:25:5258```python
Staphany Park384b99a2019-12-18 03:23:3459is_asan = true
60is_debug = false # Release build.
61```
62
63Build with:
Darwin Huang7d3b5f052019-12-23 19:25:5264```shell
Staphany Park384b99a2019-12-18 03:23:3465ninja -C out/asan base_unittests
66```
67
Alan Screenfa870a22024-04-26 00:44:3768### Reclient build
Staphany Park384b99a2019-12-18 03:23:3469
Alan Screenfa870a22024-04-26 00:44:3770ASan builds should work seamlessly with Reclient; just add
71`use_remoteexec=true` in your "gn args".
Staphany Park384b99a2019-12-18 03:23:3472
73### Build options
74
75If you want your stack traces to be precise, you will have to disable inlining
76by setting the GN arg:
Darwin Huang7d3b5f052019-12-23 19:25:5277```shell
Staphany Park384b99a2019-12-18 03:23:3478enable_full_stack_frames_for_profiling = true
79```
80
81Note that this incurs a significant performance hit. Please do not do this on
82buildbots.
83
84If you're working on reproducing ClusterFuzz reports, you might want to add:
Darwin Huang7d3b5f052019-12-23 19:25:5285```shell
Staphany Park384b99a2019-12-18 03:23:3486v8_enable_verify_heap = true
87```
Darwin Huang7d3b5f052019-12-23 19:25:5288in order to enable the `--verify-heap` command line flag for v8 in Release builds.
Staphany Park384b99a2019-12-18 03:23:3489
90## Verify the ASan tool works
91
92**ATTENTION (Linux only)**: These instructions are for running ASan in a way
93that is compatible with the sandbox. However, this is not compatible with
94LeakSanitizer. If you want to debug memory leaks, please use the instructions on
95the
Solomon Kinarda2c503022024-06-14 18:08:1896[LeakSanitizer](https://www.chromium.org/developers/testing/leaksanitizer)
Staphany Park384b99a2019-12-18 03:23:3497page instead.
98
99Now, check that the tool works. Run the following:
Darwin Huang7d3b5f052019-12-23 19:25:52100```shell
101out/asan/base_unittests \
102 --gtest_filter=ToolsSanityTest.DISABLED_AddressSanitizerLocalOOBCrashTest \
Amy Huangaaa8dcb2021-03-16 18:54:34103 --gtest_also_run_disabled_tests
Staphany Park384b99a2019-12-18 03:23:34104```
105
106The test will crash with the following error report:
Darwin Huang7d3b5f052019-12-23 19:25:52107```shell
108==26552== ERROR: AddressSanitizer stack-buffer-overflow on address \
1090x7fff338adb14 at pc 0xac20a7 bp 0x7fff338adad0 sp 0x7fff338adac8
Staphany Park384b99a2019-12-18 03:23:34110WRITE of size 4 at 0x7fff338adb14 thread T0
111 #0 0xac20a7 in base::ToolsSanityTest_DISABLED_AddressSanitizerLocalOOBCrashTest_Test::TestBody() ???:0
112 #1 0xcddbd6 in testing::Test::Run() testing/gtest/src/gtest.cc:2161
113 #2 0xcdf63b in testing::TestInfo::Run() testing/gtest/src/gtest.cc:2338
114... lots more stuff
Darwin Huang7d3b5f052019-12-23 19:25:52115Address 0x7fff338adb14 is located at offset 52 in frame \
116base::ToolsSanityTest_DISABLED_AddressSanitizerLocalOOBCrashTest_Test::TestBody()> of T0's stack:
Staphany Park384b99a2019-12-18 03:23:34117 This frame has 2 object(s):
118 [32, 52) 'array'
119 [96, 104) 'access'
120==26552== ABORTING
121... lots more stuff
122```
123
Samuel Huange9a7bff9d2020-03-04 16:16:03124Congrats, you have a working ASan build! &#x1F64C;
Staphany Park384b99a2019-12-18 03:23:34125
126## Run chrome under ASan
127
Darwin Huang7d3b5f052019-12-23 19:25:52128And finally, have fun with the `out/Release/chrome` binary. The filter script
Amy Huangaaa8dcb2021-03-16 18:54:34129`tools/valgrind/asan/asan_symbolize.py` can be used to symbolize the output,
130although it shouldn't be necessary on Linux and Windows, where Chrome uses the
131llvm-symbolizer in its source tree by default.
Staphany Park384b99a2019-12-18 03:23:34132
133ASan should perfectly work with Chrome's sandbox. You should only need to run
Alex Goughe56e8c812023-12-12 16:09:33134with `--no-sandbox` on Linux if you're debugging ASan. To get reports on Windows
135from sandboxed processes you will have to run with both `--enable-logging` and
136`--log-file=d:\valid\path.log` then inspect the logfile.
Staphany Park384b99a2019-12-18 03:23:34137
138You may need to run with `--disable-gpu` on Linux with NVIDIA driver older than
139295.20.
140
141You will likely need to define environment variable
142[`G_SLICE=always-malloc`](https://developer.gnome.org/glib/unstable/glib-running.html)
143to avoid crashes inside gtk.
Nico Weber3b6c2552020-09-09 19:49:45144`NSS_DISABLE_ARENA_FREE_LIST=1` and `NSS_DISABLE_UNLOAD=1` are required as well.
Staphany Park384b99a2019-12-18 03:23:34145
146When filing a bug found by AddressSanitizer, please add a label
Bruce Dawson07f51d22022-07-01 10:51:53147`Stability-Memory-AddressSanitizer`.
Staphany Park384b99a2019-12-18 03:23:34148
149## ASan runtime options
150
151ASan's behavior can be changed by exporting the `ASAN_OPTIONS` env var. Some of
152the useful options are listed on this page, others can be obtained from running
153an ASanified binary with `ASAN_OPTIONS=help=1`. Note that Chromium sets its own
154defaults for some options, so the default behavior may be different from that
155observed in other projects.
Michael Lippautz9236a2c2021-07-22 21:53:19156See `build/sanitizers/sanitizer_options.cc` for more details.
Staphany Park384b99a2019-12-18 03:23:34157
158## NaCl support under ASan
159
Nico Weber3b6c2552020-09-09 19:49:45160On Linux (and soon on macOS) you can build and run Chromium with NaCl under ASan.
Staphany Park384b99a2019-12-18 03:23:34161Untrusted code (nexe) itself is not instrumented with ASan in this mode, but
162everything else is.
163
Nico Weber3b6c2552020-09-09 19:49:45164To do this, remove `enable_nacl=false` from your `args.gn`, and define
Staphany Park384b99a2019-12-18 03:23:34165`NACL_DANGEROUS_SKIP_QUALIFICATION_TEST=1` in your environment at run time.
166
167Pipe chromium output (stderr) through ``tools/valgrind/asan/asan_symbolize.py
168`pwd`/`` to get function names and line numbers in ASan reports.
Darwin Huang7d3b5f052019-12-23 19:25:52169If you're seeing crashes within `nacl_helper_bootstrap`, try deleting
170`out/Release/nacl_helper`.
Staphany Park384b99a2019-12-18 03:23:34171
172## Building on iOS
173
174It's possible to build and run Chrome tests for iOS simulator (which are x86
175binaries essentially) under ASan. Note that you'll need a Chrome iOS checkout
176for that. It isn't currently possible to build iOS binaries targeting ARM.
177
178Configure your build with `is_asan = true` as described above. Replace your
179build directory as needed:
Darwin Huang7d3b5f052019-12-23 19:25:52180```shell
Staphany Park384b99a2019-12-18 03:23:34181ninja -C out/Release-iphonesimulator base_unittests
Darwin Huang7d3b5f052019-12-23 19:25:52182out/Release-iphonesimulator/iossim -d "iPhone" -s 7.0 \
183 out/Release-iphonesimulator/base_unittests.app/ \
184 --gtest_filter=ToolsSanityTest.DISABLED_AddressSanitizerLocalOOBCrashTest \
185 --gtest_also_run_disabled_tests 2>&1 |
Staphany Park384b99a2019-12-18 03:23:34186tools/valgrind/asan/asan_symbolize.py
187```
188
189You'll see the same report as shown above (see the "Verify the ASan tool works"
190section), with a number of iOS-specific frames.
191
192## Building on Android
193
194Follow [AndroidBuildInstructions](android_build_instructions.md) with minor
195changes:
196
Darwin Huang7d3b5f052019-12-23 19:25:52197```python
198target_os="android"
Darwin Huang7d3b5f052019-12-23 19:25:52199is_asan=true
200is_debug=false
201```
Staphany Park384b99a2019-12-18 03:23:34202
Darwin Huang7d3b5f052019-12-23 19:25:52203Use `build/android/asan_symbolize.py` to symbolize stack from `adb logcat`. It
204needs the `--output-directory` argument and takes care of translating the device
205path to the unstripped binary in the output directory.
Staphany Park384b99a2019-12-18 03:23:34206
Nico Weber3b6c2552020-09-09 19:49:45207## Building with v8\_target\_arch="arm"
Staphany Park384b99a2019-12-18 03:23:34208
209This is needed to detect addressability bugs in the ARM code emitted by V8 and
210running on an instrumented ARM emulator in a 32-bit x86 Linux Chromium. **You
211probably don't want this, and these instructions have bitrotted because they
212still reference GYP. If you do this successfully, please update!** See
Darwin Huang7d3b5f052019-12-23 19:25:52213https://crbug.com/324207 for some context.
Staphany Park384b99a2019-12-18 03:23:34214
215First, you need to install the 32-bit chroot environment using the
216`build/install-chroot.sh` script (as described in
217https://code.google.com/p/chromium/wiki/LinuxBuild32On64). Second, install the
218build deps:
Darwin Huang7d3b5f052019-12-23 19:25:52219```shell
220precise32 build/install-build-deps.sh \
221 # assuming your schroot wrapper is called 'precise32'
Staphany Park384b99a2019-12-18 03:23:34222```
223
224You'll need to make two symlinks to avoid linking errors:
Darwin Huang7d3b5f052019-12-23 19:25:52225```shell
226sudo ln -s $CHROOT/usr/lib/i386-linux-gnu/libc_nonshared.a \
227 /usr/lib/i386-linux-gnu/libc_nonshared.a
228sudo ln -s $CHROOT/usr/lib/i386-linux-gnu/libpthread_nonshared.a \
229 /usr/lib/i386-linux-gnu/libpthread_nonshared.a
Staphany Park384b99a2019-12-18 03:23:34230```
231
232Now configure and build your Chrome:
Darwin Huang7d3b5f052019-12-23 19:25:52233```shell
234GYP_GENERATOR_FLAGS="output_dir=out_asan_chroot" GYP_DEFINES="asan=1 \
235 disable_nacl=1 v8_target_arch=arm sysroot=/var/lib/chroot/precise32bit/ \
236 chroot_cmd=precise32 host_arch=x86_64 target_arch=ia32" gclient runhooks
Staphany Park384b99a2019-12-18 03:23:34237ninja -C out_asan_chroot/Release chrome
238```
239
240**Note**: `disable_nacl=1` is needed for now.
241
James Cook0c3837bc2021-08-12 01:30:36242## Running on Chrome OS
243
244For the linux-chromeos "emulator" build, run Asan following the instructions
245above, just like you would for Linux.
246
247For Chromebook hardware, add `is_asan = true` to your args.gn and build.
248`deploy_chrome` with `--mount` and `--nostrip`. ASan logs can be found in
Matt Turnere23adc32025-01-22 17:31:03249`/tmp/asan/`.
James Cook0c3837bc2021-08-12 01:30:36250
251To catch crashes in gdb:
252
253- Edit `/etc/chrome_dev.conf` and add `ASAN_OPTIONS=abort_on_error=1`
254- `restart ui`
255- gdb -p 12345 # Find the pid from /var/log/chrome/chrome
256
257When you trigger the crash, you'll get a SIGABRT in gdb. `bt` will show the
258stack.
259
260See
261[Chrome OS stack traces](https://chromium.googlesource.com/chromiumos/docs/+/main/stack_traces.md)
262for more details.
263
Staphany Park384b99a2019-12-18 03:23:34264## AsanCoverage
265
266AsanCoverage is a minimalistic code coverage implementation built into ASan. For
267general information see
268[https://code.google.com/p/address-sanitizer/wiki/AsanCoverage](https://github.com/google/sanitizers)
269To use AsanCoverage in Chromium, add `use_sanitizer_coverage = true` to your GN
270args. See also the `sanitizer_coverage_flags` variable for configuring it.
271
272Chrome must be terminated gracefully in order for coverage to work. Either close
273the browser, or SIGTERM the browser process. Do not do `killall chrome` or send
274SIGKILL.
Darwin Huang7d3b5f052019-12-23 19:25:52275```shell
276kill <browser_process_pid>
277ls
Staphany Park384b99a2019-12-18 03:23:34278...
279chrome.22575.sancov
280gpu.6916123572022919124.sancov.packed
281zygote.13651804083035800069.sancov.packed
282...
283```
284
285The `gpu.*.sancov.packed` file contains coverage data for the GPU process,
286whereas the `zygote.*.sancov.packed` file contains coverage data for the
287renderers (but not the zygote process). Unpack them to regular `.sancov` files
288like so:
Darwin Huang7d3b5f052019-12-23 19:25:52289```shell
290$ $LLVM/projects/compiler-rt/lib/sanitizer_common/scripts/sancov.py unpack \
291 *.sancov.packed
Staphany Park384b99a2019-12-18 03:23:34292sancov.py: unpacking gpu.6916123572022919124.sancov.packed
293sancov.py: extracting chrome.22610.sancov
294sancov.py: unpacking zygote.13651804083035800069.sancov.packed
295sancov.py: extracting libpdf.so.12.sancov
296sancov.py: extracting chrome.12.sancov
297sancov.py: extracting libpdf.so.10.sancov
298sancov.py: extracting chrome.10.sancov
299```
300
301Now, e.g., to list the offsets of covered functions in the libpdf.so binary in
302renderer with pid 10:
Darwin Huang7d3b5f052019-12-23 19:25:52303```shell
304$ $LLVM/projects/compiler-rt/lib/sanitizer_common/scripts/sancov.py print \
305 libpdf.so.10.sancov
Staphany Park384b99a2019-12-18 03:23:34306```