Clang 3.3 now supports AddressSanitizer. Here is the description from the Clang 3.3 documentation:
AddressSanitizer is a fast memory error detector. It consists of a compiler instrumentation module and a run-time library. The tool can detect the following types of bugs:
- Out-of-bounds accesses to heap, stack and globals
- Use-after-return (to some extent)
- Double-free, invalid free
Typical slowdown introduced by AddressSanitizer is 2x.
Using AddressSanitizer by manually compiling a file is well documented. On the other hand using Xcode 4.6.1 to build a complex project with AddressSanitizer enabled is not so easy. Following are the steps to build an Xcode project with AddressSanitizer.
Note that I used Xcode 4.6.1 when writing this article. Xcode 4.6.1 contains a Clang build based on LLVM 3.2. Most likely a future Xcode build will contain a Clang build based on LLVM 3.3 which would simplify the use of AddressSanitizer in Xcode.
1- Building Clang 3.3
Since Xcode 4.6.1 contains an old build of Clang, we need to get and build Clang trunk. This is fairly easy. Here is what I did:
- svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
- cd llvm/tools
- svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
- cd ../..
- cd llvm/projects
- svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
- cd ../..
- mkdir build
- cd build
- ../llvm/configure -enable-optimizations
- make -j `sysctl -n hw.logicalcpu`
2- Tell Xcode 4.6.1 to use Clang 3.3 we just compiled
The simplest solution I found is to add the following user define in the Xcode target:
CC = "PATH_TO/llvm/build/Debug+Asserts/bin/clang";
You need to set PATH_TO to the folder where you compiled llvm.
3- Make sure the deployment target is set to 10.7 or higher
I used the deployment target set to 10.7.
4- Add the C flag and linker flag
Add the C flag
Add the linker flag
5- Compile your project
Congratulations! You now have a build of your project with AddressSanitizer enabled.
6- Running the application
Xcode 4.6.1 fails to run this executable but you can run it from the Terminal and AddressSanitizer will detect possible memory errors.
If your application has a memory error, you will see an error message like:
7- Symbolize the symbols
Currently AddressSanitizer does not symbolize its output.
You will need to manually symbolize the addresses. This can easily be done with atos (see man atos) and the dSYM file produced during the compilation (you might need to turn on “DWARF with dSYM File” in the Xcode target).
For example to symbolize the symbol 0x100001d86 in the AddressSanitizer message:
Alex:MyApplication alex$ atos -o build/Debug/MyApplication.app.dSYM/Contents/Resources/DWARF/MyApplication 0x100001d86 -[AppDelegate applicationDidFinishLaunching:] (in MyApplication) (AppDelegate.mm:23)
Clang 3.3 documentation for AddressSanitizer: http://clang.llvm.org/docs/AddressSanitizer.html
AddressSanitizer HomePage: http://code.google.com/p/address-sanitizer/