Can’t symbolicate XCode4 archive builds?
Update: symbolication is fixed in Xcode 4.1. Check this post for troubleshooting tips if you’re still having problems.
Since XCode 4 was released, several iOS developers have reported that their crash reports are no longer symbolicated correctly, meaning that they can’t trace crashes to the code that caused them. I’ve traced this problem down to the Perl script that XCode uses to map the addresses in a crash report to their symbols,
symbolicatecrash. I’ve patched the script to get it working, which you can download here. This is not beautiful Perl (if there is such a thing), and it makes some assumptions about how files are nested, so YMMV. But it works for me.
Archiving in XCode 4
It’s been possible to archive a build in XCode for a while, primarily to preserve it in a place you could get to from the Organizer. In XCode 4, the archive process has been streamlined, and it’s the best way to create ad hoc builds for distributing to beta testers, and release builds to submit to the app store. Once you create an archive, you can click the Share… button in the Organizer to create an .ipa file for ad hoc distribution (I use HockeyKit for this, and many people like TestFlight, though I find their admin UI confusing). You can also click the Submit… button to re-sign the same build for app store distribution and submit to iTunes Connect, so you know you’re submitting the exact same code you’ve been testing on the device.
In XCode 3.x, Build and Archive created an .ipa file. XCode 4 introduces a new format, the .xcarchive directory, which is what leads to the symbolication problem. The symbolicatecrash script uses Spotlight to locate both the .dSYM file with the symbols, and the actual binary. In XCode 3, Spotlight would return the directories where these files could be located, and symbolicatecrash would find them. However, with .xcarchives, Spotlight returns the .xcarchive directory, and the files symbolicatecrash needs are nested a few levels within that directory. Since symbolicatecrash expects them to be directly in one of the directories returned by Spotlight, it fails to look any further, and fails to resolve the symbols.
First symbolicatecrash does a Spotlight search for the .dSYM directory for the UUID of the app from the crash log:
It expects this to return the .dSYM directory, but for XCode 4 archive builds, it returns the .xcarchive directory. If the result doesn’t match the pattern .*.dSYM, my edited version globs 2 directories deeper until it finds it.
Next symbolicatecrash does a Spotlight search for the actual executable name:
It then checks each result with otool for a UUID matching the crash log. Again Spotlight returns .xcarchive directories for all the builds archived using XCode 4, even though the actual executable is nested a few folders deeper, inside Products/Applications. My edited version of the script again globs deeper for the executable if the Spotlight result is an .xcarchive directory.
For now, the patched script works fine, so feel free to move /usr/local/bin/sybmolicatecrash aside and copy in the edited version. You can run it manually against a crash log with the -v flag to see all the dirty details. Please don’t comment on how crappy my Perl edits are, but please feel free to fork my repo and improve on it. I’ve filed this as rdar://problem/9241304