0

Docs: Improve asan.md formatting

Improves the asan.md doc formatting, mostly  as per review comments in
https://crrev.com/c/1883615/.

Change-Id: Ib4e51353b306d71f231521bd2f07944f13207c98
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1972418
Commit-Queue: Darwin Huang <huangdarwin@chromium.org>
Auto-Submit: Darwin Huang <huangdarwin@chromium.org>
Reviewed-by: Victor Costan <pwnall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#727205}
This commit is contained in:
Darwin Huang
2019-12-23 19:25:52 +00:00
committed by Commit Bot
parent 73f1202a68
commit 7d3b5f05d1

@ -4,7 +4,7 @@
error detector based on compiler instrumentation (LLVM). It is fully usable for
Chrome on Linux and Mac. There's a mostly-functional Windows port in progress
too. Additional info on the tool itself is available at
http://clang.llvm.org/docs/AddressSanitizer.html.
https://clang.llvm.org/docs/AddressSanitizer.html.
For the memory leak detector built into ASan, see
[LeakSanitizer](https://sites.google.com/a/chromium.org/dev/developers/testing/leaksanitizer).
@ -22,14 +22,12 @@ and 64 bits), Chromium OS (x86 and amd64 builds running inside VMs). Linux and
Linux Chromium OS bots run with --no-sandbox, but there's an extra Linux bot
that enables the sandbox (but disables LeakSanitizer).
The trybots running Chromium tests on Linux and OSX are: linux_asan (everything
except browser_tests and content_browsertests), linux_browser_asan
(browser_tests and content_browsertests), mac_asan (many tests including
browser_tests and content_browsertests), linux_chromeos_asan (the chromeos=1
build running on a Linux machine, many tests including browser_tests and
content_browsertests).
(Outdated) Blink bots: WebKit Linux ASAN buildbot and linux_layout_asan trybot.
The trybots running Chromium tests on Linux and macOS are:
- linux_asan (everything except browser_tests and content_browsertests)
- linux_browser_asan (browser_tests and content_browsertests),
- mac_asan (many tests including browser_tests and content_browsertests)
- linux_chromeos_asan (the chromeos=1 build running on a Linux machine, many
tests including browser_tests and content_browsertests).
## Pre-built Chrome binaries
@ -38,8 +36,8 @@ You can grab fresh Chrome binaries built with ASan
## Build tests with ASan
If you're on mac or linux64, building with ASan is easy. Start by compiling
`base_unittests` to verify the build is working for you (see below), then you
If you're on MacOS or linux64, building with ASan is easy. Start by compiling
`base_unittests` to verify the build is working for you (see below). Then, you
can compile `chrome`, `browser_tests`, etc.. Make sure to compile release
builds.
@ -50,18 +48,18 @@ details).
### Configuring the build
Create an asan build directory by running:
```
```shell
gn args out/asan
```
Enter the following build variables in the editor that will pop up:
```
```python
is_asan = true
is_debug = false # Release build.
```
Build with:
```
```shell
ninja -C out/asan base_unittests
```
@ -75,7 +73,7 @@ forget to use ninja -j <jobs> to take advantage of goma.
If you want your stack traces to be precise, you will have to disable inlining
by setting the GN arg:
```
```shell
enable_full_stack_frames_for_profiling = true
```
@ -83,11 +81,10 @@ Note that this incurs a significant performance hit. Please do not do this on
buildbots.
If you're working on reproducing ClusterFuzz reports, you might want to add:
```
```shell
v8_enable_verify_heap = true
```
in order to enable the --verify-heap command line flag for v8 in Release builds.
in order to enable the `--verify-heap` command line flag for v8 in Release builds.
## Verify the ASan tool works
@ -99,21 +96,23 @@ the
page instead.
Now, check that the tool works. Run the following:
```
out/asan/base_unittests
--gtest_filter=ToolsSanityTest.DISABLED_AddressSanitizerLocalOOBCrashTest
--gtest_also_run_disabled_tests 2>&1 | tools/valgrind/asan/asan_symbolize.py
```shell
out/asan/base_unittests \
--gtest_filter=ToolsSanityTest.DISABLED_AddressSanitizerLocalOOBCrashTest \
--gtest_also_run_disabled_tests 2>&1 | tools/valgrind/asan/asan_symbolize.py
```
The test will crash with the following error report:
```
==26552== ERROR: AddressSanitizer stack-buffer-overflow on address 0x7fff338adb14 at pc 0xac20a7 bp 0x7fff338adad0 sp 0x7fff338adac8
```shell
==26552== ERROR: AddressSanitizer stack-buffer-overflow on address \
0x7fff338adb14 at pc 0xac20a7 bp 0x7fff338adad0 sp 0x7fff338adac8
WRITE of size 4 at 0x7fff338adb14 thread T0
#0 0xac20a7 in base::ToolsSanityTest_DISABLED_AddressSanitizerLocalOOBCrashTest_Test::TestBody() ???:0
#1 0xcddbd6 in testing::Test::Run() testing/gtest/src/gtest.cc:2161
#2 0xcdf63b in testing::TestInfo::Run() testing/gtest/src/gtest.cc:2338
... lots more stuff
Address 0x7fff338adb14 is located at offset 52 in frame <base::ToolsSanityTest_DISABLED_AddressSanitizerLocalOOBCrashTest_Test::TestBody()> of T0's stack:
Address 0x7fff338adb14 is located at offset 52 in frame \
base::ToolsSanityTest_DISABLED_AddressSanitizerLocalOOBCrashTest_Test::TestBody()> of T0's stack:
This frame has 2 object(s):
[32, 52) 'array'
[96, 104) 'access'
@ -125,7 +124,7 @@ Congrats, you have a working ASan build! 🙌
## Run chrome under ASan
And finally, have fun with the `out/Release/chrome binary`. The filter script
And finally, have fun with the `out/Release/chrome` binary. The filter script
`tools/valgrind/asan/asan_symbolize.py` should be used to symbolize the output.
(Note that `asan_symbolize.py` is absolutely necessary if you need the symbols -
there is no built-in symbolizer for ASan in Chrome).
@ -156,7 +155,7 @@ See `base/debug/sanitizer_options.cc` for more details.
## NaCl support under ASan
On Linux (and soon on Mac) you can build and run Chromium with NaCl under ASan.
On Linux (and soon on MacOS) you can build and run Chromium with NaCl under ASan.
Untrusted code (nexe) itself is not instrumented with ASan in this mode, but
everything else is.
@ -165,7 +164,8 @@ To do this, remove `disable_nacl=1` from `GYP_DEFINES`, and define
Pipe chromium output (stderr) through ``tools/valgrind/asan/asan_symbolize.py
`pwd`/`` to get function names and line numbers in ASan reports.
If you're seeing crashes within `nacl_helper_bootstrap`, try deleting `out/Release/nacl_helper`.
If you're seeing crashes within `nacl_helper_bootstrap`, try deleting
`out/Release/nacl_helper`.
## Building on iOS
@ -175,10 +175,12 @@ for that. It isn't currently possible to build iOS binaries targeting ARM.
Configure your build with `is_asan = true` as described above. Replace your
build directory as needed:
```
```shell
ninja -C out/Release-iphonesimulator base_unittests
out/Release-iphonesimulator/iossim -d "iPhone" -s 7.0 out/Release-iphonesimulator/base_unittests.app/ \
--gtest_filter=ToolsSanityTest.DISABLED_AddressSanitizerLocalOOBCrashTest --gtest_also_run_disabled_tests 2>&1 |
out/Release-iphonesimulator/iossim -d "iPhone" -s 7.0 \
out/Release-iphonesimulator/base_unittests.app/ \
--gtest_filter=ToolsSanityTest.DISABLED_AddressSanitizerLocalOOBCrashTest \
--gtest_also_run_disabled_tests 2>&1 |
tools/valgrind/asan/asan_symbolize.py
```
@ -190,22 +192,24 @@ section), with a number of iOS-specific frames.
Follow [AndroidBuildInstructions](android_build_instructions.md) with minor
changes:
target_os="android"
is_clang=true
is_asan=true
is_debug=false
```python
target_os="android"
is_clang=true
is_asan=true
is_debug=false
```
Running ASan applications on Android requires additional device setup. Chromium
testing scripts take care of this, so testing works as expected:
```
build/android/test_runner.py instrumentation --test-apk ContentShellTest
--test_data content:content/test/data/android/device_files -v -v -v --tool=asan
--release
```shell
build/android/test_runner.py instrumentation --test-apk ContentShellTest \
--test_data content:content/test/data/android/device_files -v -v -v \
--tool=asan --release
```
To run stuff without Chromium testing script (ex. ContentShell.apk, or any third
party apk or binary), device setup is needed:
```
```shell
tools/android/asan/third_party/asan_device_setup.sh --lib
third_party/llvm-build/Release+Asserts/lib/clang/*/lib/linux/libclang_rt.asan-arm-android.so
# wait a few seconds for the device to reload
@ -216,11 +220,13 @@ When this is done, the device will run ASan apks as well as normal apks without
any further setup.
To run command-line tools (i.e. binaries), prefix them with `asanwrapper`:
```
```shell
adb shell /system/bin/asanwrapper /path/to/binary
```
Use `build/android/asan_symbolize.py` to symbolize stack from `adb logcat`. It needs the `--output-directory` argument and takes care of translating the device path to the unstripped binary in the output directory.
Use `build/android/asan_symbolize.py` to symbolize stack from `adb logcat`. It
needs the `--output-directory` argument and takes care of translating the device
path to the unstripped binary in the output directory.
## Building with v8_target_arch=arm
@ -228,26 +234,30 @@ This is needed to detect addressability bugs in the ARM code emitted by V8 and
running on an instrumented ARM emulator in a 32-bit x86 Linux Chromium. **You
probably don't want this, and these instructions have bitrotted because they
still reference GYP. If you do this successfully, please update!** See
[http://crbug.com/324207](https://bugs.chromium.org/p/chromium/issues/detail?id=324207)
for some context.
https://crbug.com/324207 for some context.
First, you need to install the 32-bit chroot environment using the
`build/install-chroot.sh` script (as described in
https://code.google.com/p/chromium/wiki/LinuxBuild32On64). Second, install the
build deps:
```
precise32 build/install-build-deps.sh # assuming your schroot wrapper is called 'precise32'
```shell
precise32 build/install-build-deps.sh \
# assuming your schroot wrapper is called 'precise32'
```
You'll need to make two symlinks to avoid linking errors:
```
sudo ln -s $CHROOT/usr/lib/i386-linux-gnu/libc_nonshared.a /usr/lib/i386-linux-gnu/libc_nonshared.a
sudo ln -s $CHROOT/usr/lib/i386-linux-gnu/libpthread_nonshared.a /usr/lib/i386-linux-gnu/libpthread_nonshared.a
```shell
sudo ln -s $CHROOT/usr/lib/i386-linux-gnu/libc_nonshared.a \
/usr/lib/i386-linux-gnu/libc_nonshared.a
sudo ln -s $CHROOT/usr/lib/i386-linux-gnu/libpthread_nonshared.a \
/usr/lib/i386-linux-gnu/libpthread_nonshared.a
```
Now configure and build your Chrome:
```
GYP_GENERATOR_FLAGS="output_dir=out_asan_chroot" GYP_DEFINES="asan=1 disable_nacl=1 v8_target_arch=arm sysroot=/var/lib/chroot/precise32bit/ chroot_cmd=precise32 host_arch=x86_64 target_arch=ia32" gclient runhooks
```shell
GYP_GENERATOR_FLAGS="output_dir=out_asan_chroot" GYP_DEFINES="asan=1 \
disable_nacl=1 v8_target_arch=arm sysroot=/var/lib/chroot/precise32bit/ \
chroot_cmd=precise32 host_arch=x86_64 target_arch=ia32" gclient runhooks
ninja -C out_asan_chroot/Release chrome
```
@ -264,9 +274,9 @@ args. See also the `sanitizer_coverage_flags` variable for configuring it.
Chrome must be terminated gracefully in order for coverage to work. Either close
the browser, or SIGTERM the browser process. Do not do `killall chrome` or send
SIGKILL.
```
$ kill <browser_process_pid>
$ ls
```shell
kill <browser_process_pid>
ls
...
chrome.22575.sancov
gpu.6916123572022919124.sancov.packed
@ -278,8 +288,9 @@ The `gpu.*.sancov.packed` file contains coverage data for the GPU process,
whereas the `zygote.*.sancov.packed` file contains coverage data for the
renderers (but not the zygote process). Unpack them to regular `.sancov` files
like so:
```
$ $LLVM/projects/compiler-rt/lib/sanitizer_common/scripts/sancov.py unpack *.sancov.packed
```shell
$ $LLVM/projects/compiler-rt/lib/sanitizer_common/scripts/sancov.py unpack \
*.sancov.packed
sancov.py: unpacking gpu.6916123572022919124.sancov.packed
sancov.py: extracting chrome.22610.sancov
sancov.py: unpacking zygote.13651804083035800069.sancov.packed
@ -291,6 +302,7 @@ sancov.py: extracting chrome.10.sancov
Now, e.g., to list the offsets of covered functions in the libpdf.so binary in
renderer with pid 10:
```
$ $LLVM/projects/compiler-rt/lib/sanitizer_common/scripts/sancov.py print libpdf.so.10.sancov
```shell
$ $LLVM/projects/compiler-rt/lib/sanitizer_common/scripts/sancov.py print \
libpdf.so.10.sancov
```