Manually Symbolicating iOS Crashes

In one of our iOS projects we used PLCrashReporter to capture crash reports and email them to one of our servers. Since then we have decided that Crashlytics does a much better job for a lot less work, and cost the same amount (FREE!). Because of this, we switched over to using Crashlytics, so I won’t explain how to set up PLCrashReporter, but the symbolication of crash reports can sometimes be essential.

In order to get things set up for symbolicating crash reports, you’ll need to use PLCrashUtil to convert the crash report into Xcode’s format.

Once the crash report is in Xcode’s format things are supposed to be quite simple.

Prerequisites


  1. PLCrashUtil – only required if you are using PLCrashReporter
  2. dSYMs
  3. Xcode

If you do not have the dSYMs and Xcode, there’s nothing you can do. You will have to obtain the dSYMs for the build that you received a crash report for. Usually you’ll have these if you are the one who archived the project. If you don’t have the dSYMs, you’ll probably need to contact whoever created the archive to get them. The easiest thing to do is just import the archive into Xcode.

Setup


  1. Download PLCrashReporter
    1. https://www.plcrashreporter.org/download
    2. Just download the zip version
  2. Unzip the package
  3. In the tools folder is plcrashutil
    1. If you’re going to be using plcrashutil frequently, you may want to place it in  /usr/local/bin
  4. Place the following in  ~/.bash_profile

Converting Crash Reports


In order to symbolicate the crash, you must convert the *.plcrash file into a *.crash. Do this with PLCrashUtil

This will spit the *.crash file out into the console. If you want to output it to a file you can do the following

Or if you want to try and symbolicate the crash directly, you can use the following.

Once again this will just spit everything out into the terminal. This is not particularly useful, so you probably want to just save out the *.crash file and import it into Xcode.

Unfortunately the project we were using PLCrashReporter in was distributed in nonstandard ways. We distributed the ipa to the client, they resigned the ipa with their own certificate and distributed the application with their own enterprise account. This means that the crash reports we receive need a little editing in order to symbolicate correctly.

Unless you’re in a similar situation, you can skip to the next section. You can also skip to the last section if you want to just symbolicate things line by line.

Crash reports contain the following information

  1. Metadata
  2. Stack traces for each threads
  3. Binary Images

The Binary Images section will look something like this

Each line contains

  1. A few hex addresses
  2. Framework name
  3. Framework architecture
  4. Framework UUID
  5. Framework path

The framework UUID maps directly to a particular set of dSYMs. The resigning process that our client uses requires us to change the UUID for the MyApp framework. The only reason we can do this is because we know that the dSYMs for the ipa we send our client compatible with the dSYMs for the resigned ipa.

We need to find the UUID for the dSYMs we have, and put it into the crash file we have. Run the following command to get the UUID for the dSYMs that you know are correct for the distributed ipa.

This will spit out something like this

Replace the UUID of your framework with the appropriate UUID from the output.

You should now be able to symbolicate things correctly.

Importing into Xcode


Once you have a *.crash file

  1. Open Xcode
  2. Go to the organizer
  3. In the upper left, select “Device Logs”
  4. Drag the *.crash file into the center pane

The crash report should get symbolicated automatically now. If it doesn’t, which seems to happen to me an awful lot, you’ll have to symbolicate the crash report manually.

Manual Symbolication


Sometimes, even when you’re certain you’ve done everything right, you’re still left with an unsymbolicated crash report. And eventually you reach the point where you’ve spent too much time trying to force Xcode to do what you want, and you need to just give up. When this happens, you can just use atos to query the dSYM for a particular memory address.

In the stack trace, you’ll see a line like this

The first hex code is the memory address. The second hex code is the load address. The last number is probably important somehow.

To use atos execute the following

In this case it would be 0x24000 for the load address.

This will put atos into interactive mode. Just type in an address, and it’ll output what’s at that memory address. In this case, you’d enter 0x0006c063. Once you’re done you can just hit ctrl+c to exit.

Leave a Reply

Your email address will not be published. Required fields are marked *