Advanced Crash Report Symbolication

This article assumes that you read our Bug Reporting guide and need to manually symbolicate a crash report. For most cases, simply ensuring our corresponding .dSYM files are uploaded to your crash reporting service will be sufficient.

If you have a matching binary, crash log and .dSYM file, you can symbolicate (add debugging symbols) the crash log manually using Xcode's symbolicatecrash tool:


Open bash and export your DEVELOPER_DIR as enviroment variable:

export DEVELOPER_DIR="/Applications/"

Place your .crash, .app, and all .dSYM files (your app + dynamic frameworks) in the same directory and run:

symbolicatecrash MyAppCrash.crash ./ > Symbolicated.crash

If this doesn't work, you can use -v to get more information. In most cases the reason is the binary does not match the .dSYM files. Ensure that Spotlight indexing is enabled for the location you run this on.

Bitcode Considerations

If your application ships with Bitcode, Apple will recompile it on their servers before pushing it to the App Store. This will modify symbol positions and generate a new dSYM file. Apple allows you to download these dSYMs from their server and there are also 3rd-party tools like fastlane refresh_dsyms that can automate this process.

How to Symbolicate Manually with atos

This method uses atos and is a little more advanced but worth trying if you are having trouble with the other methods.

The atos command converts numeric addresses to their symbolic equivalents. If full debug symbol information is available, for example in a .app.dSYM sitting beside a .app, then the output of atos will include file name and source line number information.

In a directory side by side you need

  • PSPDFKit.framework
  • PSPDFKit.framework.dSYM
  • mycrash.crash

Check if they are all from the same build by ensuring the UUIDs within match. To extract the UUIDs from the binary and the dSYM file:

dwarfdump PSPDFKit.framework/PSPDFKit -u
dwarfdump PSPDFKit.framework.dSYM -u

Look for the UUID for the appropriate architecture of the crash log you are examining, e.g.

UUID: 35DA91E3-AECE-300A-AB16-158B42FF78DB (arm64) PSPDFKit.framework.dSYM/Contents/Resources/DWARF/PSPDFKit

In the Binary Images section of the crash log the UUID of the framework binary has the UUID inside <...> in lower-case and without dashes. e.g.

0x1003d8000 -        0x100e47fff +PSPDFKit arm64  <35da91e3aece300aab16158b42ff78db> /Some Path to .../

The first column is the load address. In this case 0x1003d8000. The load address is given to atos so it can work out the correct offset in the dSYM file.

atos -arch arm64 -o ./PSPDFKit.framework/PSPDFKit -l 0x1003d8000

With the above line atos will read lines from stdin and attempt to symbolicate the line. But we need to find an address to give it.

   Thread 4 Crashed:
           0   PSPDFKit  0x000000010079e5b8 std::__1::__hash_table<std::__1::__hash_value_type<void*, objc_object* __weak>...

Instead of letting atos read from stdin we can instead pass addresses immediately. After the load address you can pass a whitespace separated list of addresses to symbolicate

atos -arch arm64 -o ./PSPDFKit.framework/PSPDFKit -l 0x1003d8000 0x000000010079e5b8

atos should then print out the line.

Note: The same procedure applies to applies to PSPDFKitUI.framework.

Solving Symbolication Problems

There are several resources that help if you have troubles symbolicating your crash logs.