Monday, February 25, 2013

static analysis with llvm

Using Scan Build

LLVM comes with a static analyzer - http://clang-analyzer.llvm.org. It works by overriding CC. So, to use it with autoconf'ed project, you need to first run it when running configure and then make. On Ubuntu you can always apt-get it, but if you are interested in building from source then take a look at my other post.
$ scan-build ./configure
$ scan-build make
In some case, esp. if you are building from source, scan-build may not find clang. So you will need to explicitly, pass the path to clang to scan-build. E.g. if clang is installed (via make install) at /proj/staging/llvm, then you will need to pass --use-analyzer to scan-build.

$ scan-build --use-analyzer=/proj/staging/llvm/bin/clang ./configure
$ scan-build --use-analyzer=/proj/staging/llvm/bin/clang make

Integrating Clang Static Analyzer into Makefile.am

Alex has a different approach to running scan build. In this post, he shows how to include a step to run the analyzer in every build. This is really neat because there is no change to your standard build flow. Every time you run make, it automatically calls the analyzer (or not if you don't include the step to all-local).

The flip side is that you need to use clang as the compiler only and not gcc or any other compiler. 

More Details on Clang Static Analyzer

More details on LLVM's static analyzer is available at http://clang-analyzer.llvm.org/scan-build.html.

Example of a Bug that Clang Static Analyzer found

I ran scan-build against wayland source some time back and caught a bug immediately - https://bugs.freedesktop.org/show_bug.cgi?id=61385.

To incorporate Alex's idea, a small patch to src/Makefile.am is required. Just add the following changes to Wayland's src/Makefile.am and then rebuild. Note that you must use clang as the compiler in this case.

+analyzer_srcs =                                      \
+    $(filter %.c, $(libwayland_util_la_SOURCES))     \
+    $(filter %.c, $(libwayland_server_la_SOURCES))   \
+    $(filter %.c, $(libwayland_client_la_SOURCES))
+
+analyzer_plists = $(analyzer_srcs:%.c=%.plist)
+
+$(analyzer_plists): %.plist: %.c
+       @echo "  CCSA  " $@
+       @$(COMPILE) --analyze $< -o $@
+
+all-local: $(analyzer_plists)
+
+MOSTLYCLEANFILES = $(analyzer_plists)

No comments: