Demystifying iOS Application Crash Logs

This is a blog post by Soheil Moayedi Azarpour, an independent iOS developer. You can also find him on Google+. Have you ever had the following experience as an app developer? Before you submit your app, you perform a lot of testing to make sure your app runs flawlessly. It works fine on your device, […] By Soheil Azarpour.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 6 of this article. Click here to view the first page.

A Sample Crash Log

Let’s start by taking a look at a sample crash log, so that you have an idea of what to expect before tackling some real scenarios.

Without further ado, meet your new friend:

// 1: Process Information
Incident Identifier: 30E46451-53FD-4965-896A-457FC11AD05F
CrashReporter Key:   5a56599d836c4f867f6eec76afee451bf9ae5f31
Hardware Model:      iPhone4,1
Process:         Rage Masters [4155]
Path:            /var/mobile/Applications/A5635B22-F5EF-4CEB-94B6-FE158D885014/Rage Masters.app/Rage Masters
Identifier:      Rage Masters
Version:         ??? (???)
Code Type:       ARM (Native)
Parent Process:  launchd [1]

// 2: Basic Information
Date/Time:       2012-10-17 21:39:06.967 -0400
OS Version:      iOS 6.0 (10A403)
Report Version:  104

// 3: Exception
Exception Type:  00000020
Exception Codes: 0x000000008badf00d
Highlighted Thread:  0

// 4: Threads backtraces
Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0:
0   libsystem_kernel.dylib        	0x327f2eb4 mach_msg_trap + 20
1   libsystem_kernel.dylib        	0x327f3048 mach_msg + 36
2   CoreFoundation                	0x36bd4040 __CFRunLoopServiceMachPort + 124
3   CoreFoundation                	0x36bd2d9e __CFRunLoopRun + 878
4   CoreFoundation                	0x36b45eb8 CFRunLoopRunSpecific + 352
5   CoreFoundation                	0x36b45d44 CFRunLoopRunInMode + 100
6   CFNetwork                     	0x32ac343e CFURLConnectionSendSynchronousRequest + 330
7   Foundation                    	0x346e69ba +[NSURLConnection sendSynchronousRequest:returningResponse:error:] + 242
8   Rage Masters                  	0x000d4046 0xd2000 + 8262

Thread 1:
0   libsystem_kernel.dylib        	0x32803d98 __workq_kernreturn + 8
1   libsystem_c.dylib             	0x3a987cf6 _pthread_workq_return + 14
2   libsystem_c.dylib             	0x3a987a12 _pthread_wqthread + 362
3   libsystem_c.dylib             	0x3a9878a0 start_wqthread + 4

// 5: Thread state
Thread 0 crashed with ARM Thread State (32-bit):
    r0: 0x00000000    r1: 0x00000000      r2: 0x00000001      r3: 0x39529fc8
    r4: 0xffffffff    r5: 0x2fd7d301      r6: 0x2fd7d300      r7: 0x2fd7d9d0
    r8: 0x2fd7d330    r9: 0x3adbf8a8     r10: 0x2fd7d308     r11: 0x00000032
    ip: 0x00000025    sp: 0x2fd7d2ec      lr: 0x001bdb25      pc: 0x30301838
  cpsr: 0x00000010

// 6: Binary images
Binary Images:
0xd2000 -    0xd7fff +Rage Masters armv7  <f37ee6d2c7b334868972e0e9c54f7062> /var/mobile/Applications/A5635B22-F5EF-4CEB-94B6-FE158D885014/Rage Masters.app/Rage Masters
0x2fe41000 - 0x2fe61fff  dyld armv7  <75594988728831d98e1f7c4c7b7ca29d> /usr/lib/dyld
0x327f2000 - 0x32808fff  libsystem_kernel.dylib armv7  <f167dacec44b3a86a8eee73400ff7a83> /usr/lib/system/libsystem_kernel.dylib
0x328a8000 - 0x328bdfff  libresolv.9.dylib armv7  <e79b59a3406f34d9b37f8085955115ce> /usr/lib/libresolv.9.dylib
0x32a70000 - 0x32b35fff  CFNetwork armv7  <3e973794a4d13428bb974edcb2027139> /System/Library/Frameworks/CFNetwork.framework/CFNetwork
0x32b7a000 - 0x32cc3fff  libicucore.A.dylib armv7  <0253932c1b9038a0849ef73c38e076ca> /usr/lib/libicucore.A.dylib
0x32cc4000 - 0x32cc5fff  CoreSurface armv7  <b3f9d4e8dd803a48b88c58a0663d92a3> /System/Library/PrivateFrameworks/CoreSurface.framework/CoreSurface
0x32f65000 - 0x32f8afff  OpenCL armv7  <f7706501012430fc94ed99006419fba9> /System/Library/PrivateFrameworks/OpenCL.framework/OpenCL

There is a lot of mysterious stuff in this report. :] Let’s go through it section-by-section:

(1) Process Information

This first section gives you some information about the process that crashed.

  • Incident Identifier is a unique identifier for the crash report.
  • CrashReporter Key is also a unique key that is mapped to the device identifier. Although it is anonymized, it gives you a very useful piece of information: if you see 100 crash logs from the same CrashReporter Key or a few CrashReporter Keys, it means that the issue might not be a widespread problem, limited to only one or a few devices.
  • The Hardware Model identifies the device type. If you get a lot of crashes from the same device model, it might mean that your app is not working properly on a specific model. In the log above, the device is an iPhone 4s.
  • Process is the name of the application. The number in the brackets is the process ID of the application at the time of crash.
  • The next few lines should be self-explanatory.

(2) Basic Information

This section gives you some basic information about the date and time of the crash, and the version of iOS running on the device. If you have a lot of crash logs coming from iOS 6.0, it might mean that your problem is specific to iOS 6.

(3) Exception

In this section, you can see the type of exception that was thrown at the time of the crash. You also get the exception code and the thread that threw the exception. Depending on the type of crash report, you may get some extra information in this section as well.

(4) Threads backtraces

This section provides the backtrace log for all threads in the app. Backtrace is a list of all active frames at the time of the crash. It gives you a list of function calls when the crash happened. Consider the line below:

2    XYZLib    0x34648e88    0x83000 + 8740

It is basically four columns:

  1. The frame number – in this case, 2.
  2. The name of the binary – in this case, XYZLib.
  3. The address of the function that was called – in this case, 0x34648e88.
  4. The fourth column is divided into two sub-columns, a base address and an offset. Here it is 0x83000 + 8740, where the first number points to the file, and the second points to the line of code in that file.

(5) Thread state

This section gives you the values in the registers at the time of crash. You don’t usually need this section, because the backtrace has already given you the information you need to find your problem.

(6) Binary images

This section lists all the binaries that were loaded at the time of the crash.

Demystification with Symbolication

When you first look at the backtrace in a crash log, it doesn’t make sense. You’re used to working with function names and line numbers, not a cryptic location like this:

6    Rage Masters    0x0001625c    0x2a000 + 30034

The process of converting from these hexidecimal addresses in the executable code to method names and line numbers is called symbolification.

When you get crash logs off of a device through Xcode’s Organizer window, they are automatically symbolicated after a few seconds. The symbolicated version of the above line is this:

6    Rage Masters    0x0001625c    -[RMAppDelegate application:didFinishLaunchingWithOptions:] (RMAppDelegate.m:35)

For Xcode to symbolicate a crash log, it needs to have access to the matching application binary that was uploaded to the App Store, and the .dSYM file that was generated when that binary was built. This must be an exact match; otherwise, the report cannot be fully symbolicated.

So, it is essential that you keep each build distributed to users. When you archive your app before submission, Xcode stores your binary. You can find all of your archived applications in the Xcode Organizer under the Archives tab.

Xcode will automatically symbolicate all crash reports that it encounters, if it has the matching .dSYM and application binary that produced the crash report. If you are switching computers or creating a new account, make sure you move over all of those binaries and put them in the right place, where Xcode can find them.

Note: You must keep both the application binary and the .dSYM file to be able to fully symbolicate crash reports. You should archive these files for every build that you submit to iTunes Connect.

The .dSYM and application binary are specifically tied together on a per-build-basis, and subsequent builds, even from the same source files, will not interoperate with files from other builds.

If you use the Build and Archive command, the files will be placed in a suitable location automatically. Otherwise, any location searchable by Spotlight (such as your home directory) is fine.

Note: You must keep both the application binary and the .dSYM file to be able to fully symbolicate crash reports. You should archive these files for every build that you submit to iTunes Connect.

The .dSYM and application binary are specifically tied together on a per-build-basis, and subsequent builds, even from the same source files, will not interoperate with files from other builds.

If you use the Build and Archive command, the files will be placed in a suitable location automatically. Otherwise, any location searchable by Spotlight (such as your home directory) is fine.

Contributors

Over 300 content creators. Join our team.