Infinite Loop

Code Coverage with Xcode 4.2

This tutorial is just a small follow-up on one of my earlier posts about how to set up code coverage in Xcode.

With the release of Xcode 4.2 code coverage is finally supported using Clang / LLVM. Opposed to what I described in the earlier post you no longer need to force the use of GCC to get code coverage metrics in your unit tests. Since Apple has also decided to drop support for GCC you are more or less forced to switch to Clang / LLVM anyway.

In Xcode 4.2 it’s fairly simple to set up code coverage. If you have defined a custom build setting or build rule that enforces GCC 4.2 you will need to remove those first.

Next you’ll need to enable the two build settings “Generate Test Coverage Files” and “Instrument Program Flow” as shown below:


[AdSense - blog banner]

Under the Linker settings you may also notice that the “-lgcov” linker flag has been removed. This is because code coverage on Clang / LLVM is now supported by the “profile_rt” library. Unfortunately it’s a bit tricky to find this library because Apple for whatever reason decided not to include it in the default library path. Instead you’ll have to manually navigate to /Developer/usr/lib/ to link against it:

That’s all there is to it.

Just run your unit tests and view the code coverage data as usual.

The updated Xcode project can be downloaded from GitHub.

Comments (26) | Trackback

26 Responses to “Code Coverage with Xcode 4.2”

  1. Jon Reid says:

    When I try this, all my tests run, but then it crashes with “Detected an attempt to call a symbol in system libraries that is not present on the iPhone: fopen$UNIX2003 called from function llvm_gcda_start_file”.

    I think I’ll have to stick with GCC for coverage until Apple cleans this up.

    • Claus Broch says:

      I have not experienced this problem myself, but it could very well be some internal call that Apple needs to solve.

      On my computer I actually have two versions of the libprofile_re.dylib file. The one in the location mentioned in the blog post is the newest but there is also a file located in /Developer/Platforms/iPhoneOS.platform/Developer/usr/lib/ so you might have better luck using that instead.

      Another thing that might be worth mentioning is that the library is Intel-only (i386 and x86_64), so you are not able to run theses tests on the iPhone itself if you want code coverage metrics.

    • Claus Broch says:

      Jon, you may need to trim your linker and compiler flags down to a bare minimum as this seems to lead to all kinds of spurious errors according to this post by Jon Boydell.

  2. Josh Brown says:

    Jon – I had the same problem and found that I hadn’t linked against the libprofile_re.dylib library. Here are the steps to do that, from Jon Boydell’s post):

    4. Add the following library to the “Build Phases” of the test target. That is:
    4a. Go test target settings then “Build Phases” tab
    4b. Go “Link Binary With Libraries”
    4c. Go “+”, then “Add Other..”
    4d. Go “/Developer/usr/lib/libprofile_rt.dylib” which will add it to the list of things to link

  3. Josh Brown says:

    I’m only seeing coverage on my unit test files, which is obviously not very useful. What could be causing this? I’m tempted to try “Generate Test Coverage Files” and “Instrument Program Flow” on my main target, but that seems like it’s going to cause problems on release builds. Where can I look to see what I did wrong?

  4. Jon Reid says:

    I still can’t get things to work. And I’m puzzled that Jon Boydell’s post says to make the changes to your unit test target, because I expect that to deliver the results you got: your tests are instrumented.

    With my old gcc-based setup, I have a Coverage configuration, and make coverage-specific changes in the main target (actually, at the project level) within this configuration.

  5. Josh Brown says:

    I just got this working. I set “Generate Test Coverage Files” and “Instrument Program Flow” on the **main** target, in the Debug configuration. This caused an error (“fopen$UNIX2003 called from function llvm_gcda_start_file”), then [Stack Overflow](http://stackoverflow.com/questions/8732393/code-coverage-with-xcode-4-2-missing-files) helped me to resolve that.

  6. wingyip says:

    XCode 4.2, LLVM GCC 4.2. Mac Os X application.
    I have enabled “Generate Test Coverage Files” and “Instrument Program Flow”and add the libprofile_rt.dylib in the build phases. But after running the application, still no .gcda and .gcon files found in the object files folder. Is there anything wrong?

  7. [...] coverage metrics. The configuration has evolved quite a bit but fortunately there’s a great Code Coverage with Xcode 4.2 guide from Infinite Loop that covers this and seems to work with both Xcode 4.3 and 4.4 in my testing. Be sure to check the [...]

    • Zahed says:

      hey there and thank you for your information – I have celrainty picked up something new from right here. I did however expertise a few technical issues using this website, as I experienced to reload the website lots of times previous to I could get it to load properly. I had been wondering if your hosting is OK? Not that I’m complaining, but sluggish loading instances times will very frequently affect your placement in google and can damage your high quality score if ads and marketing with Adwords. Well I’m adding this RSS to my email and can look out for a lot more of your respective interesting content. Make sure you update this again soon..

  8. David Hersey says:

    Thank you so much for this post! I pulled my hair out getting this to work — after following these instructions I was only able to see .gcno files in my build directory.

    I set UIApplicationExitsOnSuspend flag in my Info.plist to YES.
    I changed GCC_PRECOMPILE_PREFIX_HEADER to NO.

    I also realized I did not include the correct libprofile_rt library — it should be libprofile_rt.dylib in the “link binary with libraries” build setting.

    Now I was getting .gcda files, finally — but they all showed NO COVERAGE!

    I think this was because I am using GHUnit, which runs from the simulator and/or device.

    I then followed the steps in THIS posting: http://gabriel.github.com/gh-unit/docs/appledoc_include/guide_command_line.html to get the GHUnit tests to run from the command line, and Voila! It works.

    FWIW, I recommend people use the command-line approach to generate the coverage report — it is easy to just kick that off then refresh the CoverStory window to see the results.

    It can also be easily integrated with CI tools like Jenkins (http://gabriel.github.com/gh-unit/docs/appledoc_include/guide_ci.html)

    Good luck!

  9. [...] followed Claus’s post to set up code coverage on Xcode 4.2 with LLVM 3.0. I’m able to see test coverage files, but [...]

  10. Cyril says:

    thanks for your post, it was helpful!

    I worked on integrating other quality metrics in Jenkins, you can find my insights here: http://blog.octo.com/en/jenkins-quality-dashboard-ios-development

    You will see that concerning code coverage, I explained how to setup it for both OCUnit and GHUnit and updated the instructions for Xcode 4.3. I improved also the way the coverage is reported (exhaustiveness, structure).

  11. [...] two most popular blog posts on how to get code coverage for the iPhone can be found here and here. Follow them and you will only get the coverage for the files that are actually tested by [...]

  12. When using Xcode from the App Store, this is the new location of the libprofile_rt.dylib:
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libprofile_rt.dylib

  13. Sanjeet says:

    I am trying to setup code coverage on xcode 4.6 on mountain lion. I do not see the mentioned library profile_rt in developers/usr/lib. Do you know why this mau be happening?

  14. [...] out that Apple uses the profile_rt library to handle code coverage instead of the former gcov library, which is why the _llvm_gcda_start_file function symbol is [...]

  15. Kamlesh Mallick says:

    Hi guys,

    This blog is useful. Thank you so much.

    I compile my C++ code using GCC but then, CODE coverage is not supported by the LLVM-GCC 4.2 compiler in OSX. And thus am using CLang++ compiler, which generates the .gcno files along with the object files (.o)

    Now when i link my code against – libprofile_rt.dylib

    I get Linker Errors

    Undefined symbols for architecture i386:
    “_llvm_gcda_emit_arcs”, referenced from:

    What could be the problem?
    Should i not compile my C++ code using CLang++?
    Or Should i link against some other library?

    Any answers would be appreciated.

    • Claus Broch says:

      I don’t have any experience using code coverage with C++ so I’m unfortunately not able to provide you with much help.

      Have you tried forlowing some of the advice in the comments posted by other people?

      • Kamlesh Mallick says:

        Hi Claus,

        Thanks for the reply.
        No problem at all, your post did help by guiding me towards the elusive library i was supposed to link to – libprofile_rt.dylib

        I got those linker errors as the dynamic library – libprofile_rt.dylib was built for architecture x86_64 and i was compiling my code for i386.

        So i built my code for architecture x86_64 and i thought that would eliminate the error but apparently not.
        I still get linker errors regarding “_llvm_gcov_init”

        linking /ac/h/library/src/MtxLib/build/unix/macosx/debug/libMtx.so for unix/macosx/debug
        Undefined symbols for architecture x86_64:
        “_llvm_gcov_init”, referenced from:
        ___llvm_gcov_init in Iso9660Reader.o
        ___llvm_gcov_init in AutoExtractCreator.o
        ___llvm_gcov_init in TempFilePath.o
        ___llvm_gcov_init in TempPath.o
        ___llvm_gcov_init in ReadDirectory.o
        ___llvm_gcov_init in OpenDirectory.o
        ___llvm_gcov_init in SpltPath.o

        Thanks again, i shall continue my research and post any solution when i find it.

  16. […] two most popular blog posts on how to get code coverage for the iPhone can be found here and here. Follow them and you will only get the coverage for the files that are actually tested […]

Leave a Reply

*