# Obtain the source code and set up Git $ git clone http://llvm.org/git/llvm.git $ cd llvm/tools $ git clone http://llvm.org/git/clang.git $ cd clang $ git config branch.master.rebase true $ cd ../.. $ git config branch.master.rebase true # You should be in the llvm parent directory # Prepare your object directory. This is where all your compiled files go (similar to Mozilla object dirs) $ mkdir obj $ cd obj # Configure with optimized builds set to install in /usr/local/llvm # We build optimized because it is a last faster. You can use any --with-prefix # path, but the following instructions assume /usr/local/llvm. $ ../configure --enable-optimized --with-prefix=/usr/local/llvm $ make -s6 $ make install # At this point, you should have LLVM and Clang installed in /usr/local/llvm # Test by executing: $ /usr/local/llvm/bin/clang --version clang version 3.1 (firstname.lastname@example.org:indygreg/clang.git http://llvm.org/git/clang.git 53ba95612c023ecbcf142b9aaa90e4082fc1b480) Target: x86_64-apple-darwin11.2.0 Thread model: posix
Configuring Build Environment
clang++binaries are the ones you just installed:
$ export PATH=/usr/local/llvm/bin:$PATH $ which clang /usr/local/llvm/bin/clang
.mozconfig, add the following:
Please note that the location of these tools should be the full path to Clang source code you obtained earlier. At the time this was written, these tools were not installed as part of
A full working .mozconfig for the desktop browser is: CC=/Users/gps/src/llvm/tools/clang/tools/scan-build/ccc-analyzer CXX=/Users/gps/src/llvm/tools/clang/tools/scan-build/c++-analyzer . $topsrcdir/browser/config/mozconfig mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-ff-dbg mk_add_options MOZ_MAKE_FLAGS="-s --no-print-directory -j6" ac_add_options --enable-debug
Attempts to use ccache will likely result in failure to compile. It is also necessary to avoid optimized builds, as these will modify macros which will result in many false positives.
Now, force your build tree to pick up the changes by re-running configure:
$ cd /path/to/mozilla/source # Blow away your object directory because incremental builds don't make sense $ rm -rf obj-dir $ make -f client.mk configure # The above should execute without any errors. However, it should take longer than # normal because all compilation will be executing through Clang's static analyzer, # which adds overhead.
At this point, your Mozilla build environment should be configured to compile via the Clang static analyzer!
Performing Scanning Builds
It is not enough to simply start the build like normal. Instead, you need to run the build through a Clang utility script which will keep track of all produced analysis and consolidate it automatically.
That script is
scan-build. You can find it in
Try running your build through scan-build:
$ cd obj-ff-dbg $ /Users/gps/src/llvm/tools/clang/tools/scan-build/scan-build make -j6 --no-print-directory
If things are working properly, you should see a bunch of console spew, just like any build.
The first time you run scan-build, CTRL+C after a few files are compiled. You should see output like:
scan-build: 3 bugs found. scan-build: Run 'scan-view /Users/gps/tmp/mcsb/2011-12-15-3' to examine bug reports.
If you see a message like:
scan-build: Removing directory '/var/folders/s2/zc78dpsx2rz6cpc_21r9g5hr0000gn/T/scan-build-2011-12-15-1' because it contains no reports.
either no static analysis results were available yet or your environment is not configured properly.
scan-build writes results to a folder in a pseudo-temporary location. You can control where results go by passing the
-o /path/to/output arguments to
$ /Users/gps/src/llvm/tools/clang/tools/scan-build/scan-build -o ~/scan-build make -j6 --no-print-directory
You may also want to run
scan-build --help to see all the options available. It is possible to selectively enable and disable individual analyzers, for example.
Once the build has completed,
scan-build will produce a report summarizing all the findings. This is
index.html in the output directory. You can run
scan-build's output suggests. This merely fires up a local HTTP server. Or, you should be able to open the
index.html directly with your browser.
There are currently many false positives in the static analyzer. A lot of these are due to the analyzer having difficulties following the relatively complicated error handling in various preprocessor macros. For example, most of our
ASSERT() macros call other functions which themselves call
assert() or do something else.
Long term, we should add a set of macros enabled via
#ifdef which provide simple macros understandable by the static analyzer. There are also some pragmas and compiler extensions we can investigate using to silence warnings.
For now, an easy way to circumvent false positives is to import changes made to indygreg's (gps on IRC) GitHub branch, foster_static_analysis.
$ git remote add indygreg git://github.com/indygreg/mozilla-central.git $ git fetch indygreg $ git merge indygreg/foster_static_analysis
Then, run scan-build with the changes and you should see far fewer false positives!