Finding Memory Leaks With The LLVM/Clang Static Analyzer

 

While you may be familiar with using tools like Instruments to find and fix memory leaks in your application, the Clang Static Analyzer takes a different approach to memory leak detection by compiling your Xcode project and scanning each method, class, loop, and logic block for potential leaks. You may have heard of the Clang Static Analyzer referred to by the name of the command line tool used to run the analyzer: scan-build. That is how I will be referring to it for the remainder of this post.

Requirements & Where To Get It

scan-build is currently only available in binary form for OS X 10.5.
If you haven’t yet downloaded scan-build head on over to the LLVM/Clang Static Analyzer homepage and look for the Download section at the bottom of the page. Click the link for checker-NN.tar.gz (where NN is some build number). At the time of this writing the link reads checker-72.tar.gz. The developers of scan-build are very active so I have no doubt that the build number is already different.

Installation

Since scan-build is a command line tool it makes sense to install it into one of OS X’s pre-defined command line tool locations. We’ll put it in /usr/local/bin.

  1. Make sure that you’ve expanded checker-NN.tar.gz to your Downloads folder
  2. We’re going to be installing the checker binaries into your /usr/local/bin directory.  Run the following command to ensure that this directory exists:
  3. Â sudo mkdir -p /usr/local/bin
    
  4. Open Terminal.app and move the contents of checker-NN to the /usr/local/bin directory (remember to replace NN with the build number of your download):
    sudo mv ~/Downloads/checker-NN/* /usr/local/bin/
    

Basic Usage

scan-build tests your code by compiling your Xcode project and studying it for defects during the build process. To check your code, you just invoke scan-build from the command line at the top level of any one of your project directories.

  1. Still in Terminal.app, change into one of your Xcode project directories
  2. Run scan-build on your Xcode project:
  3. scan-build xcodebuild
    

    There’s quite a bit of output when scan-build runs, but once it finishes running you will either see

    ** BUILD SUCCEEDED **
    scan-build: No bugs found.
    

    or something similar to

    ** BUILD SUCCEEDED **
    
    scan-build: 7 bugs found.
    
    scan-build: Open '/tmp/scan-build-fw1RAD/2008-07-31-1/index.html' to examine bug reports.
    
  4. Copy the section similar to Open ‘/tmp/scan-build-fw1RAD/2008-07-31-1/index.html’, paste it back onto the command line and hit return.
  5. You’ll be presented with the Summary screen. Click on the View link next to each bug to see your code with an inset bubble describing the bug that scan-build found

iPhone Usage

Using scan-build with the iPhone requires a little extra tweaking in your Xcode project settings to make sure that you are compiling your project using an SDK that is compatible with scan-build’s compiler.  The rest of these instructions assume a project who’s configuration has not been modified beyond what is provided when you create a new project.  I will be working with a project titled WhatsMyIP.

  1. Open the iPhone Xcode project that you want to run scan-build on and bring up the project settings panel.
    Open Project Settings
  2. On the General tab change the Base SDK for All Configurations to one of the Simulator SDKs.
    Project Settings - General
  3. Switch over to the Build tab and scroll down to the Code Signing section.  Change both the Code Signing Identity and the entry under it to Don’t Code Sign.
    projectsettings-build
  4. After making these changes you should be able to run scan-build on your iPhone project successfully.

Customizing Your Output

After running scan-build a few times the first thing that you might want to do is tell scan-build to put its reports in a different directory. To do that, simply specify the output folder on the command line like so:
scan-build -o /path/to/the/directory/where/you/want/your/report xcodebuild

There are a few other flags that can be passed to scan-build, but for now the reports that are generated should be the same regardless of the flags you set. Check out the Other Options section on the Static Analyzer usage page for the full (but still pretty short) list of available options.

Wrap Up

One thing to note is that scan-build is still in pre-1.0 and has some rough edges. You may notice some false-positives or other undesirable behavior. As with any pre-release software use it at your own risk and always have a backup of your work. That being said, I have not had nor heard of any disastrous problems with it, so your risk is probably pretty low.

A lot of folks in the OS X development community have gotten a lot of use out of scan-build in the past few months. One of the larger scale uses of it can be found on the Adium project, you can view the results of their static analysis here.

Good luck!

This entry was posted in Cocoa, Debugging.

44 thoughts on “Finding Memory Leaks With The LLVM/Clang Static Analyzer

  1. Ted Kremenek says:

    The static analyzer is actually 100% open source as part of the Clang project, so those who wish to build the source directly can do so by visiting http://clang.llvm.org.

    I do know of users who have used the analyzer to scan source code in FreeBSD, so anyone who can build Clang from source is welcome to give the analyzer a try (not just OS X developers). We’re just not providing pre-built binaries for a bunch of platforms at this time. The binaries we do provide right now should be viewed as a little more than a nightly build, as we roll in bug fixes and feature improvements every couple of days.

    I think characterizing the tool as pre-1.0 is very accurate. There are many things we would like to do improve the tool’s analysis precision, workflow, expand the kind of checks it performs, etc. Any suggestions for how to improve the tool are extremely welcome!

  2. Jon Trainer says:

    Try using the -V option to automatically open the report in your default browser — Saves you a step.

  3. Pingback: Yeah it's past 3:30am and i am stuck - iPhone Dev SDK Forum

  4. Pingback: Image memory at Under The Bridge

  5. Pingback: Memory leak detection made easy.

  6. Adam Wulf says:

    very handy guide, thank you!

    i’m struggling with my first iphone app and running into memory problems, and this is certain to help. huge thanks!

  7. peter JC says:

    Hello great guide. I followed it point to point using Xcode 3.1.2 and checker 0.175, but when I run it on a toy project for the mac) where I introduced a few errors.. even though it just says

    scan-build: Removing directory ‘/var/folders/jB/jBcDCHWzH-8NL2tGNUqWzk+++TM/-Tmp-/scan-build-2009-03-14-1′ because it contains no reports.

    ?? and there is no scan-build: success or scan-build: error

    any ideas on what is going on here?

  8. Michael says:

    If you’d like to send me the sample project (with the errors commented) I’d be more than happy to take a look at it. It’s very possible that since my writing of the original article that the output has been changed and they no longer report success or error explicitly.

  9. peter JC says:

    I would love to send you a sample project, but it seams to me the the problem is that, even though it finds errors the output is not created? And I of course hoped someone ha seen the same problem

  10. to Peter JC
    I see the same error but unfortunately haven’t found a fix as of yet

  11. Greg Kaiser says:

    I am using 10.5 Mac, sdk 2.2.1, Clang 0.196 and I am not a registered ($99 type) developer. I get the exact same error. Anyone made progress on this?

  12. Pingback: Getting Clang to work – Hopefully « Greg’s Online CS 193P Resources

  13. Joe D'Andrea says:

    Same thing here. I get that error even though I follow all instructions to the letter. :\

  14. Joe D'Andrea says:

    Ahh:

    2009-06-18 15:01:56.229 xcodebuild[1676:613] warning: compiler ‘com.apple.compilers.llvm.clang.1_0.analyzer’ is based on missing compiler ‘com.apple.compilers.llvm.clang.1_0.analyzer’

    Methinks that has a little something to do with it. :-o

  15. Rudi Farkas says:

    Hello Michael

    I have been using Clang 0.193 on iPhone projects under SDK 2.2.1 with success (heeding your advice above under iPhone Usage – many thanks).

    Now I installed the SDK 3.0 and tried to use Clang:
    scan-build -k -v -V xcodebuild -configuration Debug
    As it was failing, I installed the build 0.211 – same problems.

    1—
    “”"
    Compiler: /Developer/Applications/checker-0.211/libexec/ccc-analyzer
    Reason: gcc-4.0: installation problem, cannot exec ‘/Developer/usr/bin/arm-apple-darwin9-gcc-4.0.1′: No such file or directory
    “”"

    I have a gcc-4.0.1 in
    /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/
    I created a symlink in /Developer/usr/bin/
    arm-apple-darwin9-gcc-4.0.1 -> /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin9-gcc-4.0.1

    This worked – on to the next problem

    2—
    “”"
    In file included from /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:31,
    from …
    /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UILocalizedIndexedCollation.h:13: error: syntax error before ‘AT_NAME’ token
    /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UILocalizedIndexedCollation.h:21: error: syntax error before ‘}’ token
    /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UILocalizedIndexedCollation.h:23: fatal error: method definition not in @implementation context
    compilation terminated.
    {standard input}:32:FATAL:.abort detected. Assembly stopping.
    “”"

    I am stuck here.
    Can you help, or tell me who to report the problem to ?

    Rudi

  16. Michael says:

    Rudi,

    After a short but of Googling I found these two pages that may shed some light on your problem:
    http://iphonedevelopertips.com/xcode/error-syntax-error-before-at_name-token.html
    - and -
    http://www.iphonedevsdk.com/forum/iphone-sdk-tools-utilities/19342-ui-kit-error-sdk-3-0-a.html

    The first one is just a hint about what to look for with your particular error, “error: syntax error before ‘AT_NAME’ token”. What it basically says is that this error shows up you are missing an @end somewhere in one of your included header files.

    The second link says that the missing @end is in UIKit.h and removing that import should fixed the problem. Personally I find it a little hard to believe that there would be a problem in something as fundamental as UIKit.h, but check it out and see what you get. My typical rule for bugs like this is that 99% of the time the bug is in your code – the other 1% of the time the bug is also in your code. Let me know what you come up with, I’m interested to see how this works out. If you are still running into problems and can send me your project I’d be more than happy to put a fresh set of eyes on it.

    Best of luck,
    Michael

  17. Manu says:

    try to “Clean All Targets” in build menu before launching clang. If clang doesn’t build it itself, it has nothing to say ;-)

  18. Pingback: Clang for iPhone - syntax error before ‘AT_NAME’ token

  19. Rudi Farkas says:

    Hello Michael

    I followed your links and I googled some more for “syntax error before ‘AT_NAME’ token”. Manifestly many developers are seeing this problem, and the workaround consists in commenting out line 31 in UIKit.h : #import

    I confirm that this workaround … works.

    I went one step further and looked into UILocalizedIndexedCollation.h.

    Line 13 – the first one showing in the failing diagnostic, is
    UIKIT_EXTERN @interface UILocalizedIndexedCollation : NSObject

    Deleting the UIKIT_EXTERN or commenting it out with /**/also constitutes an effective workaround.

    I have no idea why this would be so. UIKIT_EXTERN is defined in UIKitDefines.h

    #ifdef __cplusplus
    #define UIKIT_EXTERN extern “C” __attribute__((visibility (“default”)))
    #else
    #define UIKIT_EXTERN extern __attribute__((visibility (“default”)))
    #endif

    and it is used in many other .h files in UIKit.

    I reproduced the problem on a freshly made SDK 3.0 iPhone project. If you want to investigate, try to follow the following steps :

    1. Create a fresh 3.0 View-based project TryClangOn30

    2. scan-build -k -v -V xcodebuild -configuration Debug

    Code Sign error: The identity ‘iPhone Developer’ doesn’t match any valid certificate/private key pair in the default keychain
    ** BUILD FAILED **

    3. Change General : Base SDK for All Configurations : iPhoneSimulator 3.0
    Change Build : Code Signing Identity : Don’t Code Sign
    Any iPhone OS Device : Don’t Code Sign

    4. scan-build -k -v -V xcodebuild -configuration Debug

    In file included from /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:31,
    from /Users/rudifarkas/iPhoneDev/RudisProjects/TryClangOn30/TryClangOn30_Prefix.pch:7,
    from :1:
    /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UILocalizedIndexedCollation.h:13: error: syntax error before ‘AT_NAME’ token
    /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UILocalizedIndexedCollation.h:21: error: syntax error before ‘}’ token
    /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UILocalizedIndexedCollation.h:23: fatal error: method definition not in @implementation context
    compilation terminated.
    {standard input}:32:FATAL:.abort detected. Assembly stopping.

    This is as far as I got – not very far. Any ideas on the real nature of this problem would be appreciated.

    Rudi

  20. David says:

    Hi,

    I followed this tutorial to the ‘t’, however in the terminal window I get the following error “-bash: scan-build: command not found”.

    Can someone point me in the right direction. Thanks.

  21. Rudi Farkas says:

    David

    It looks like scan-build is not in your $PATH.
    Where did you put scan-build? – use Spotlight to find it
    What directories are in your $PATH? – run echo $PATH to find out

    Rudi

  22. Rudi Farkas says:

    Hello MIchael and all

    I found the solution to the problem with UILocalizedIndexedCollation.h in thread :
    http://stackoverflow.com/questions/1078001/clang-giving-errors-complaining-about-defective-header-file-uilocalizedindexedcol

    It works.
    Rudi

    The problem comes from SDK 3.0 which now use gcc 4.2 but scan-build still use /usr/bin/gcc. So you need to tell scan-build to use /usr/bin/gcc-4.2 instead.

    scan-build –use-cc=/usr/bin/gcc-4.2 xcodebuild -configuration Debug

    Et voila!

    answered Jul 8 at 9:07
    Djiss

  23. Michael says:

    Very nice! I was fairly certain that commenting out sections of library header files was not the way to go, so thanks for tracking down the answer!

  24. Michael says:

    David, how did you make out? Did Rudi’s suggestion of putting scan-build in your $PATH work out?

    Make sure that you’ve done steps 1 & 2 in the Installation section above. Once they are done you should have a file named scan-build in /usr/local/bin

  25. JCoop says:

    I have done this but it still gives me the errors. At this point I just want to remove clang because my project was working perfectly before. How can I remove clang so that it doesn’t give me these errors with perfectly written library headers.

  26. Michael says:

    J,

    You shouldn’t need to uninstall Clang as it does not modify your source code. If you made changes to any library header files either recover an old version of them from a Time Machine backup or reinstall the SDK.

    – Michael

  27. Pingback: iPhone Development: Updating Project Hint « Core Fruition

  28. David P. says:

    Thanks very much for this entry. I followed your directions to use the Clang Static Analyser on my iPhone app and it seemed to work. I was surprised that my application was already perfect and I got the message:

    ** BUILD SUCCEEDED **
    scan-build: Removing directory ‘/var/folders/sn/snToecKZEieI90xsA+sCSE+++TI/-Tmp-/scan-build-2009-07-31-1′ because it contains no reports.

    I tried inserting some code which I thought should trip the analysis. Still get the same message. If I insert something which causes the compile to fail, the build fails. If I insert a memory leak, it is not discovered. I assume that I am doing something wrong, but don’t have a clue where to look.

  29. Maulik says:

    Hi Michael thanks for the post. Even i am getting the same error like David P.

  30. Maulik says:

    Type your comment here

    Maulik :

    Hi Michael thanks for the post. I tried all the tweaks that you mentioned and finally could get the complete error report on 2.2.1 build. But when i build a project of 3.0 there is an error. I am posting the error message:

    The following build commands failed:
    SampleApp:

    CompileC build/SampleApp.build/Release-iphonesimulator/SampleApp.build/Objects-normal/i386/RootViewController.o /Developer/Maulik/SampleApp/Classes/RootViewController.m normal i386 objective-c com.apple.compilers.gcc.4_0

    CompileC build/SampleApp.build/Release-iphonesimulator/SampleApp.build/Objects-normal/i386/FormPage.o /Developer/Maulik/SampleApp/Classes/FormPage.m normal i386 objective-c com.apple.compilers.gcc.4_0

    CompileC build/SampleApp.build/Release-iphonesimulator/SampleApp.build/Objects-normal/i386/AccountDetails.o /Developer/Maulik/SampleApp/Classes/AccountDetails.m normal i386 objective-c com.apple.compilers.gcc.4_0

    This was the error message that i got. It seems it cant build this .m files and convert them to .o I couldnot understand what is wrong. It would be great if you can show some pointers as to why this happening.
    .

  31. Brian says:

    Howdy,

    I’ve been using clang off and on with my iPhone app. It seems that we get a new sdk every month or so and every time that happens clang stops working. Since the docs, ahem, suck I gotta say that it’s a pain to figure out what changed each time and make it work.

    I think I’ve finally figured it out and it ends up being simpler than I thought. This command line works for me today with the iPhone 3.1beta3 SDK installed:

    scan-build -k -V xcodebuild -sdk iphonesimulator3.1 -configuration Debug

    Some comments: as some have mentioned in previous comments xcodebuild needs to use the correct compiler. Rather than using –use-cc I think that specifying the sdk on the command line also makes xcodebuild use the correct compiler. If you type

    xcodebuild -showsdks

    It shows the names of all the sdks that it knows about. You must use a Simulator sdk (for some reason). You also need to specify the build configuration as Debug. Release doesn’t work for some reason. If you have more than one target you also need to specify the target.

    Using this command line I don’t have to turn off code signing in the project and it doesn’t matter what the base sdk, active sdk etc are in the project.

    I’m hoping that when I get the next beta this command line will still work.

  32. Michael says:

    Thanks for the great tip, Brian.

  33. Michael says:

    Maulik, check out Brian’s comment below and see if that helps you out.

  34. Michael says:

    David, that’s very strange, I haven’t run into that issue. Check out Brian’s comment below and see if that helps you out.

  35. Joe D'Andrea says:

    Has anyone been able to make Clang play nicely with Joe Hewitt’s Three20 library?

    When I run Clang on Three20 itself, it’s fine. When I run Clang on my app (which uses libThree20.a), Clang (via StaticAnalyzer) reports: “libThree20.a, file is not of required architecture” … followed by a lot of undefined symbols (of course) and no output. :(

    Clues welcome/appreciated!

  36. Joe D'Andrea says:

    I spoke too soon! It works. It was pilot error. In short, I did everything EXCEPT add Three20 as a direct dependency. The app compiled in spite of that, but Clang didn’t buy it. :)

    For those experiencing similar issues, read the README that comes with Three20 and follow “Adding Three20 to your project” step by step. (I mistakenly skipped Step 4! Tsk-tsk.) Once you do that, I’m confident it will work just fine.

  37. Luke Du says:

    Hi there,

    I’ve got an error I just can not resolve whatsoever,

    When I run “scan-build -k -V xcodebuild -configuration Debug -sdk iphonesimulator3.0″

    Error: “scan-build: The directory ‘/tmp’ does not exist or cannot be accessed.”

    Look forward to hearing from you soon.

  38. Michael says:

    Luke,

    Open Terminal.app and type ‘ls -l /’ (without the quotes).

    If the tmp directory does not exist you can create it by typing ‘mkdir /tmp’ (again, without the quotes).

    If the tmp directory does exist you will need to modify your permissions on it. Take a look at the man page for chmod (‘man chmod’) to see how to modify the permissions of this directory for your user. You may have to be root to modify the permissions.

  39. Scott says:

    Is clang working for anyone else when analyzing a project that contains a 3.0 library such as MessageUI?

    I keep getting an error “MessageUI/MessageUI.h: No such file or directory”.

    It builds fine if I just do an ‘xcodebuild’ or build within xcode.

    I have tried setting the basesdk for all to 2.2, and I have tried :

    scan-build -k -V xcodebuild -configuration Debug -sdk iphonesimulator2.2

    scan-build -k -V xcodebuild -configuration Debug -sdk iphonesimulator2.1

    scan-build -k -V xcodebuild -configuration Debug

    scan-build -k -V xcodebuild

    Doing some searches it seems like it may have to do witht the fact that this is a 3.0 library ?

  40. Scott says:

    I just found my own answer:

    THIS WORKED:

    scan-build -k -V xcodebuild -configuration Debug -sdk iphonesimulator3.0

  41. Huy says:

    That worked for me on the first shot, thanks Brian. Beautiful tool. Great time saver.

  42. Brett says:

    I am also having the “scan-build: Removing directory because it contains no reports.” problem. I have tried changing the project properties to “iphone simulator 3.1″ and “no code signing”. I have moved the binaries to /usr/local/bin. I did a clean in Xcode. I’ve tried “–use-cc=/usr/bin/gcc-4.2″ (this created another error about an invalid base, and I noticed that /usr/bin/gcc was already pointing to /usr/bin/gcc-4.2). I am using version 2.31. I am not seeing any errors related to SSE in the console. Any other suggestions?

  43. Brett says:

    I forgot to mention the command I am using is

    scan-build -k -V xcodebuild -sdk iphonesimulator3.1 -configuration Debug

  44. Michael says:

    Brett,

    I’m afraid that I’m in the dark on this one too, hopefully someone else will have some more knowledge. What version of OS X are you running? If you are using Snow Leopard the static analyzer tool is now built into Xcode, so that may fix/bypass your problem completely.

    Here’s a link: http://developer.apple.com/mac/library/featuredarticles/StaticAnalysis/index.html

    Best,
    Michael