Skip to content

Crash logs

A crash report is written to the device the moment a process dies. Getting it off the phone and into a readable state is what this module does.

  1. Connect the device that crashed — reports live on the device that produced them.
  2. Open Crash logs.
  3. Find the entry by app name and timestamp.
  4. Export, or read it in place.

Reports accumulate. Deleting the ones you have finished with keeps the list usable, and the module can do that too.

A raw report is addresses. Symbolication turns those addresses back into function names and line numbers.

For that to work, the symbols have to match the binary that crashed — same version, same build. Keep the dSYM for every build you ship; without it, your own frames stay hexadecimal no matter what tool you use. System frames symbolicate from the OS symbols for that iOS version.

Work through it in this order.

1. Exception type. The single most informative line.

Type Usually means
EXC_BAD_ACCESS (SIGSEGV) Dereferenced something that was not there — a released object, a bad pointer
EXC_CRASH (SIGABRT) An uncaught exception, a failed assertion, or a deliberate abort()
EXC_BREAKPOINT (SIGTRAP) A Swift runtime trap — force-unwrapped nil, array out of range, forced cast
EXC_RESOURCE Exceeded a resource limit, commonly memory or CPU-over-time
0x8badf00d Watchdog. The app took too long to launch or to respond, and iOS killed it
0xdead10cc Held a file lock or a shared resource while suspended

2. Terminating description. When present, it names the assertion or the exception directly. Read it before the backtrace.

3. The crashed thread. Marked as such. This is the stack that matters.

4. Your frames. Scan down the crashed thread for your own binary. System frames above it are usually just the path in; the topmost frame in your code is where to start.

Two entries in the list look like crashes and are not:

  • Jetsam / memory reports. The process was terminated for using too much memory. There is no bug at the top of the stack; the bug is the allocation trend leading up to it. Confirm with a memory trace in Performance.
  • Watchdog terminations. The main thread was blocked. Again, the backtrace shows where it was blocked, not what put it there — look for synchronous I/O or a lock.
  1. Get the report from the device that produced it. A similar device is not the same device.
  2. Read the live log around the timestamp — the app’s last words are often more useful than the stack.
  3. Check the usage history for what else was happening at that moment.
  4. Check the device information: iOS version, free storage, battery health. “Only on that phone” often turns out to be “only when the disk is full”.

Live logs · Performance monitoring · Device information