Tuesday, October 14, 2008


Many of us have wanted Valgrind on OS X for a long time, and now we finally have it, thanks to Greg Parker. Valgrind provides some impressive dynamic analysis that complements the static analysis we can get from clang's checker. This interview with the original author has a good description of what it does and how it works.

I've used Valgrind a bit, and it has earned its place in my toolbox. Here are some things I've learned.

While the LLVM checker analyzes your source files and tries to check every possible code path, Valgrind analyzes your built executable and only checks the code path that you specify. LLVM's checker uses lexical analysis and hypothetical variable values to point out problems. Valgrind, on the other hand, translates your executable's machine code into an instrumented bytecode representation, and runs that code in a virtual machine. There are no hypothetical values, so the accuracy of the results is much higher, but the coverage is drastically reduced.

Valgrind instruments ALL of the code that your executable executes, including libraries/frameworks/bundles that were linked against or dynamically loaded. This is possible because Valgrind's input is the machine code that you execute, not the source code that you compile. This provides tremendous opportunities for us to help improve the quality of the binaries we use, but do not own.

With the previous two paragraphs in mind, it is important to note that the actual code path taken by an executable can differ from launch to launch, even when launched repeatedly with the same arguments. Maybe a system cache gets updated, or one of your linked frameworks decides to contact an update server, etc. When your code exercises different paths, different code paths get checked.

Valgrind has a firm grip on your RAM. If you overflow or underflow a buffer on the heap, you'll hear about it. If you read from or write to freed memory, you'll hear about it. If you allocate with new and deallocate with delete[], you'll hear about it.

Valgrind can catch some errors that clang's checker cannot, and vice versa. And there are other errors that both tools will catch. By using these two tools on all of our projects, we can improve our code as well as other people's code that we use at runtime.

Hat's off to the devs who've worked on Valgrind and LLVM's checker. I wish we had these tools a long time ago.

Update: Branch merged to trunk. Thanks to Dan for the heads-up in comments.