AddressSanitizer (ASAN)

AddressSanitizer (ASAN) is a fast memory error detector based on compiler instrumentation (LLVM).
It is fully usable for Chrome on Linux and Mac.
Additional info on the tool itself is available at http://clang.llvm.org/docs/AddressSanitizer.html.


Pre-built Chrome binaries

You can grab fresh Chrome binaries for Linux built with ASAN here

Build tests with ASan

If you're on mac or linux64, building with Asan is easy:

Make sure you've run tools/clang/scripts/update.sh (see https://code.google.com/p/chromium/wiki/Clang for details).

Linux64 build:
GYP_GENERATORS=ninja GYP_DEFINES='asan=1 linux_use_tcmalloc=0 ' gclient runhooks
ninja -C out/Release base_unittests
Start with base_unittests and verify your build is working (see below).  Then you can make ... chrome or make ... browser_tests.

Mac build:
    GYP_GENERATORS=ninja GYP_DEFINES='asan=1 release_extra_cflags="-g" component=static_library' gclient runhooks
    export DYLD_NO_PIE=1  # not needed on 10.7 or later
    ninja -C out/Release base_unittests

Mac Note: you must export the DYLD_NO_PIE=1 env var when building and running ASan-enabled binaries on Snow Leopard, otherwise the dynamic loader will randomize the load address, which may hang ASan at startup. This variable is not supported on Lion and Mountain Lion, but you shouldn't have such problems there.
If your build is stuck while running a host binary like genrule, genmacro or pdfsqueeze, you've most certainly forgotten to export DYLD_NO_PIE=1.
Mac Note #2: there currently are problems with component=shared_library under ASan (see http://code.google.com/p/address-sanitizer/issues/detail?id=82). Please use static_library instead.

On both Linux64 and Mac, building with ninja instead of make should just work. Make sure to do a release build.

Goma build:
Please refer to https://groups.google.com/a/google.com/forum/#!topic/goma-users/xDDxSmfxzuY. Note that the argument -fasan is obsolete; use -fsanitize=address instead.

Build options
If you want your stack traces to be precise, you will have to disable inlining: 
GYP_DEFINES='... release_extra_cflags="-g -O1 -fno-inline-functions -fno-inline" ' gclient runhooks

Verify the ASan tool works

Now, check that the tool works. Run the following: 

export LLVM_SYMBOLIZER_PATH=third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer
# strict_memcmp=0 - http://crbug.com/178677
# replace_intrin=0 - http://crbug.com/162461 (Mac only)
# symbolize=false - http://crbug.com/243255 (Linux only)
export ASAN_OPTIONS="strict_memcmp=0 symbolize=false replace_intrin=0"
out/Release/base_unittests --gtest_filter=ToolsSanityTest.DISABLED_AddressSanitizerLocalOOBCrashTest --gtest_also_run_disabled_tests 2>&1 | tools/valgrind/asan/asan_symbolize.py | c++filt

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
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
...
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'
==26552== ABORTING

Congrats, you have a working ASan build! :-)

Run chrome under ASan
And finally, have fun with the out/Release/chrome binary. The filter script tools/valgrind/asan/asan_symbolize.py (and, optionally, c++filt) 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).

ASan should perfectly work with Chrome's sandbox. You should only need to run with --no-sandbox on Linux if you're debugging ASan.

You may need to run with --disable-gpu on Linux with NVIDIA driver older than 295.20.

You will likely need to define environment variable G_SLICE=always-malloc to avoid crashes inside gtk.
NSS_DISABLE_ARENA_FREE_LIST=1 and NSS_DISABLE_UNLOAD=1 are required as well.

When filing a bug found by AddressSanitizer, please add a label Stability-AddressSanitizer.

NaCl support under ASan

On Linux (and soon on Mac) 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.

To do this, remove disable_nacl=1 from GYP_DEFINES, and define NACL_DANGEROUS_SKIP_QUALIFICATION_TEST=1 in your environment at run time.

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.


Building on iOS

It's possible to build and run Chrome tests for iOS simulator (which are x86 binaries essentially) under ASan. Note that you'll need a Chrome iOS checkout for that. It isn't currently possible to build iOS binaries targeting ARM.

Fix chromium.gyp_env to use ASan.

$ cp ios/build/chromium.gyp_env ios/build/chromium.gyp_env.orig $ cat ios/build/chromium.gyp_env.orig | sed "s/\('GYP_DEFINES.*\)',/\1 asan=1 clang_use_chrome_plugins=0',/" > ios/build/chromium.gyp_env
Fix build/common.gypi (won't be needed after https://codereview.chromium.org/15570002/ is landed):

wget https://codereview.chromium.org/download/issue15570002_19001.diff -O arclite.patch --no-check-certificate
patch -p1 -i arclite.patch
Then update Clang and prepare the build env:
tools/clang/scripts/update.sh
gclient runhooks
export ASAN_BIN=`pwd`/third_party/llvm-build/Release+Asserts/bin/ export CC=$ASAN_BIN/clang export CXX=$ASAN_BIN/clang++

    Now build the test binary and run it:

xcodebuild -project base/base.xcodeproj -target base_unittests -sdk iphonesimulator
# TODO(glider): need to automate the following step
cp  third_party/llvm-build/Release+Asserts/lib/clang/3.3/lib/darwin/libclang_rt.asan_osx_dynamic.dylib xcodebuild/Debug-iphonesimulator/base_unittests.app/
xcodebuild/ninja-iossim/Debug/iossim xcodebuild/Debug-iphonesimulator/base_unittests.app/ \
    --gtest_filter=ToolsSanityTest.DISABLED_AddressSanitizerLocalOOBCrashTest --gtest_also_run_disabled_tests 2>&1 | tools/valgrind/asan/asan_symbolize.py

You'll see the same report as shown above (see the "Verify the ASan tool works" section), with a number of iOS-specific frames.

Advanced stuff

Linux/Mac build using a custom Clang:
If for some reason you need to build a 32-bit Chrome binary, you'll need to do some magic. The same command is needed to use a custom compiler binary:
cd src
ASAN_BIN=/path/to/clang/bin
export CC="$ASAN_BIN/clang"
export CXX="$ASAN_BIN/clang++"
GYP_GENERATORS=ninja GYP_DEFINES='asan=1 linux_use_tcmalloc=0 release_extra_cflags="-g" clang_use_chrome_plugins=0 target_arch=ia32' gclient runhooks
ninja -C out/Release base_unittests

Comments