What is Address Sanitizer?
Address Sanitizer (ASan) is a fast memory error detector that detects use-after-free and out-of-bound bugs in C/C++ programs. It uses a compile-time instrumentation to check all reads and writes during the execution. In addition, the runtime part replaces the
free functions to check dynamically allocated memory. More information on how ASan works can be found at on the Address Sanitizer wiki.
The ASan instrumentation is implemented as an LLVM pass and integrated into Clang. Therefore, we must first get and build LLVM and Clang.
The following commands do a fresh SVN checkout/build of LLVM, Clang and the compiler runtime libraries with a revision confirmed to work:
REV=148325 # You can alter this if you want to try newer revisions. svn co -r $REV http://llvm.org/svn/llvm-project/llvm/trunk llvm cd llvm export LLVM_HOME=`pwd` # We will refer to this variable later during the build. (cd tools && svn co -r $REV http://llvm.org/svn/llvm-project/cfe/trunk clang) (cd projects && svn co -r $REV http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt)
Now we can start our build, which can take a while depending on your machine specs. Adjust the
-j parameter to your needs depending on your CPUs:
mkdir build (cd build && ../configure --enable-optimized && make -j 10)
ASan runtime library
Parts of the ASan code are in a runtime library which is included now in the compiler-rt repository that we checked out and built earlier. The default installation target builds a
.a file that is linked to all executables built with Clang (but not to shared objects, which is why they will have unresolved symbols). To build the runtime library we perform the following steps:
cd $LLVM_HOME/projects/compiler-rt/lib/asan make -f Makefile.old get_third_party make -f Makefile.old test -j 10 make -f Makefile.old install
Getting the source
The following build process was last tested with mozilla-central revision ad79ffdf94a3. Using that or any later revision, all you need to do is to get yourself a clone of mozilla-central.
Creating the ASan blacklist file
We must exclude certain functions from being instrumented because they will cause problems:
- Certain recursive parser functions in the JS engine can produce large stack frames (but are not really interesting for us to check)
jsgc.cppscans memory and thereby touches ASan redzones (will cause a false positive).
To prevent these from being instrumented, we create a file called
asan-blacklist.txt in our mozilla-central directory with the following content:
fun:_ZN2js6Parser* fun:_ZN2js13FoldConstants* fun:_ZN2js8frontend.Emit* fun:_ZN2js8frontend..Emit* fun:_ZL.Emit* fun:_ZL..Emit* fun:_ZN2jsL23MarkRangeConservativelyEP8JSTracerPKmS3_ fun:_ZN2jsL23MarkRangeConservativelyEP8JSTracerPKjS3_
Adjusting the build configuration
Create the build configuration file
.mozconfig with the following content in your mozilla-central directory:
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-ff-asan mk_add_options MOZ_MAKE_FLAGS=-j12 # Enable ASan specific code and build workarounds ac_add_options --enable-address-sanitizer # Ensure you set this to your LLVM_HOME path export LLVM_HOME="/path/to/your/llvm" # Ensure you adjust this export BLACKLIST="-mllvm -asan-blacklist=/path/to/your/mozilla-central/asan-blacklist.txt" # Set CC/CXX based on LLVM_HOME export CC="$LLVM_HOME/build/Release+Asserts/bin/clang" export CXX="$LLVM_HOME/build/Release+Asserts/bin/clang++" # Add ASan to our compiler flags, including blacklist export CFLAGS="-faddress-sanitizer $BLACKLIST -Dxmalloc=myxmalloc" export CXXFLAGS="-faddress-sanitizer $BLACKLIST -Dxmalloc=myxmalloc" # Additionally, we need the ASan flag during linking. Normally, our C/CXXFLAGS would # be used during linking as well but there is at least one place in our build where # our CFLAGS are not added during linking. # Note: The use of this flag causes Clang to automatically link the ASan runtime :) export LDFLAGS="-faddress-sanitizer" # These two are required by ASAn ac_add_options --disable-jemalloc ac_add_options --disable-crashreporter # Keep symbols to symbolize ASan traces later export MOZ_DEBUG_SYMBOLS=1 ac_add_options --enable-debug-symbols ac_add_options --enable-valgrind ac_add_options --disable-install-strip # Settings for a debug build ac_add_options --disable-optimize ac_add_options --enable-debug # Settings for an opt build #ac_add_options --enable-optimize="-O1 -g" #ac_add_options --disable-debug
Starting the build process
Now you start the build process using the regular
make -f client.mk command.
After the build has completed, you can start Firefox from the
objdir as usual.
XRE_NO_WINDOWS_CRASH_DIALOG=1before starting, this doesn't seem to be required anymore.
BLACKLIST to match your setup. The blacklist file should contain the same functions as for Firefox. Once you have adjusted everything, execute this script in the
js/src/ subdirectory and pass a directory name as the first parameter. The build will then be created in a new subdirectory with that name.
#! /bin/sh if [ -z $1 ] ; then echo "usage: $0 <dirname>" elif [ -d $1 ] ; then echo "directory $1 already exists" else autoconf2.13 mkdir $1 cd $1 LLVM_ROOT="/path/to/llvm" BLACKLIST="-mllvm -asan-blacklist=/path/to/asan-blacklist.txt" CC="$LLVM_ROOT/build/Release+Asserts/bin/clang" \ CXX="$LLVM_ROOT/build/Release+Asserts/bin/clang++" \ CFLAGS="-faddress-sanitizer $BLACKLIST -Dxmalloc=myxmalloc" \ CXXFLAGS="-faddress-sanitizer $BLACKLIST -Dxmalloc=myxmalloc" \ ../configure --enable-debug --disable-optimize --enable-valgrind --enable-address-sanitizer make -j 8 fi
Troubleshooting / Known problems
No symbols in crash traces
As the ASan homepage already explains, ASan does not (yet) have an in-process symbol resolver. Therefore, all crash traces will only contain addresses. fortunately, ASan comes with a python script, that will resolve the addresses to files, lines and mangled function names. You can find it at
You can then run the result through
c++filt to get readable function names.
Currently, the default options for optimized builds will fail due to an issue with -O2/-Os and ASan. The following combination of flags was briefly tested though and seems to work:
# Settings for an opt build working with ASan export MOZ_DEBUG_SYMBOLS=1 ac_add_options --enable-debug-symbols ac_add_options --enable-optimize="-O1 -g" ac_add_options --disable-debug ac_add_options --enable-valgrind
The optimized build has only a barely noticable speed penalty and seems to be even faster than regular debug builds.
Crashes on Ubuntu 11.10
There seems to be a bug on Ubuntu 11.10 where binaries such as
shlibsign and other NSS tools just crash on startup. In conjunction you'll see warnings like
/usr/bin/ld.bfd.real: /path/to/llvm/build/Release+Asserts/bin/../lib/clang/3.1/lib/linux/libclang_rt.asan-x86_64.a(asan_thread_registry.o)(.text+0x2d6): unresolvable R_X86_64_PLT32 relocation against symbol `memcpy@@GLIBC_2.2.5'
during the build. The exact cause is currently not known but it might be a bug in
ld on that Ubuntu version, as using
gold as the linker resolves the problem. To work around this problem, just do
sudo apt-get install binutils-gold
gold will be your default linker. This comes with the positive side effect that your build will be a few minutes faster due to less linking time required.