text: Understanding and Analyzing Application Crash Reports
  When an application crashes, a crash report is created which is very useful for understanding what caused the crash. This document contains essential information about how to symbolicate, understand, and interpret crash reports.
  Introduction. Devices window..
  Acquiring Crash and Low Memory Reports
  Debugging Deployed iOS Apps discusses how to retrieve crash and low memory reports directly from an iOS device.
  Analyzing Crash Reports in the App Distribution Guide discusses how to view aggregate crash reports collected from TestFlight beta testers and users who have downloaded your app from the App Store.
  Symbolicating Crash Reports. Depending on the Debug Information Format (
  DEBUG_INFORMATION_FORMAT) build setting, these debug symbols are stored inside the binary or in a companion Debug Symbol (
  dSYM) file. By default, debug builds of an application store the debug symbols inside the compiled binary while release builds of an application store the debug symbols in a companion
  dSYMfile to reduce the binary size.
  The Debug Symbol file and application binary are tied together on a per-build-basis by the build UUID. .
  dSYMfile and store them at a location inside your home folder.file when uploading your archive to iTunes Connect. In the submission dialog, check “Include app symbols for your application…”. Uploading your
  dSYMfilefile.
  The symbolicated crash reports are made available to you in Xcode's Crashes organizer.
  Bitcode. The App Store makes the
  dSYM files generated during bitcode compilation available for you to download, from Xcode or from the iTunes Connect website. You must download these
  dSYM files in order to symbolicate crash reports received from App Review or from users who have sent you crash reports from their devices. Crash reports received through the crash reporting service will be symbolicated automatically.
  Downloading the dSYM files from Xcode
  In the Archives organizer, select the archive that you originally submitted to the App Store.
  Click the Download dSYMs button.
  Xcode downloads the
  dSYM files and inserts them into the selected archive.
  Downloading the dSYM files from the iTunes Connect website
  Open the App Details page.
  Click Activity.
  From the list of All Builds, select a version.
  Click the Download dSYM link.
  Translating 'hidden' symbol names back to their original names .
  dSYM files with obfuscated symbols such as "__hidden#109_" before sending your app to iTunes Connect. Xcode creates a mapping between the original symbols and the "hidden" symbols and stores this mapping in a
  .bcsymbolmap file inside the application archive. Each .
  dSYM file will have a corresponding
  .bcsymbolmap file.
  Before symbolicating crash reports, you will need to de-obfuscate the symbols in the .
  dSYM files downloaded from iTunes Connect. If you use the Download dSYMs button in Xcode, this de-obfuscation will be performed automatically for you. However, if you use the iTunes Connect website to download the .
  dSYM files, open Terminal and use the following command to de-obfuscate your symbols (replacing the example paths with your own archive and the dSYMs folder downloaded from iTunes Connect):
  Run this command for each .
  dSYM file inside the dSYMs folder you downloaded.
  Determining Whether a Crash Report is Symbolicated..
  Symbolicating iOS Crash Reports With Xcode
  Xcode will automatically attempt to symbolicate all crash reports that it encounters. All you need to do for symbolication is to add the crash report to the Xcode Organizer.
  Connect an iOS device to your Mac
  Choose "Devices" from the "Window" menu
  To symbolicate a crash report, Xcode needs to be able to locate the following:
  The crashing application's binary and
  dSYMfile.
  The binaries and
  dSYMfiles for all custom frameworks that the application links against. For frameworks that were built from source with the application, their
  dSYMfiles are copied into the archive alongside the application's
  dSYMfile. For frameworks that were built by a third-party, you will need to ask the author for the
  dSYMfile.
  Symbols for the OS that the that application was running on when it crashed. These symbols contain debug information for the frameworks included in a specific OS release (e.g. iOS 9.3.3). OS symbols are architecture specific - a release of iOS for 64.
  Symbolicating Crash Reports With atos. Note the name of the binary image in the second column, and the address in the third column.
  Look for a binary image with that name in the list of binary images at the bottom of the crash report. Note the architecture and load address of the binary image.
  atos.
  Locate the
  dSYMfile for the binary. You can use Spotlight to find the matching
  dSYMfile for the UUID of the binary image. See the Symbolication Troubleshooting section.
  dSYMfiles are bundles in which reside a file containing the DWARF debugging information generated by the compiler at build time. You must provide the path to this file, not to the
  dSYMbundle, when invoking
  atos.
  With the above information you can symbolicate addresses in the backtrace using the
  atoscommand. You can specify multiple addresses to symbolicate, separated by a space.
  atos -arch <Binary Architecture> -o <Path to dSYM file>/Contents/Resources/DWARF/<binary image name> -l <load address> <address to symbolicate>
  Listing 1 Example usage of the
  atos command following the steps above, and the resulting output.
  Symbolication Troubleshooting.
  Look for a binary image with that name in the list of binary images at the bottom of the crash report. This list contains the UUIDs for each of the binary images that were loaded into the process at the time of the crash.
  Listing 2 You can use the
  grepcommand line tool to quickly find the entry in the list of binary images.
  Convert the UUID of the binary image to a 32 character string seperated in groups of 8-4-4-4-12 (
  XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX). Note that all letters must be uppercased.
  mdfindcommand line tool using the query
  "com_apple_xcode_dsym_uuids == <UUID>"(include the quotation marks).
  Listing 3 Using the
  mdfindcommand line tool to search for
  dSYMfiles with a given UUID.
  If Spotlight finds a
  dSYMfile for the UUID,
  mdfindwill print the path to the
  dSYMfile and possibly its containing archive. If a
  dSYMfile for the UUID was not found,
  mdfindwill exit without printing anything.. See Downloading the dSYM files from Xcode.
  If you think that you have the correct
  dSYM for the binary image, you can use the
  dwarfdump command to print the matching UUIDs. You can also use the
  dwarfdump command to print the UUIDs of a binary.
  xcrun dwarfdump --uuid <Path to dSYM file>
  If you no longer have this archive, you should submit a new version of your application for which you retain the archive. You will then be able to symbolicate crash reports for this new version.
  Analyzing Crash Reports
  This section discusses each of the sections found within a standard crash report.
  Header
  Every crash report begins with a header.
  Listing 4 Excerpt of the header from a crash report.
  Most of the fields are self-explanatory but a few deserve special note:
  Incident Identifier: A unique identifier for the report. Two reports will never share the same Incident Identifier.
  CrashReporter Key: An anonymized per-device identifier. Two reports from the same device will contain identical values.
  Beta Identifier: A unique identifier for the combination of the device and vendor of the crashed application. Two reports for applications from the same vendor and from the same device will contain identical values. This field is only present in crash reports generated for applications distributed through TestFlight, and replaces the CrashReporter Key field.
  Process: The executable name for the process that crashed. This matches the value for the
  CFBundleExecutablekey in the application's information property list.
  Version: The version of the process that crashed. The value for this field is a concatenation of the crashed application's
  CFBundleVersionand
  CFBundleVersionString.
  Code Type: The target architecture of the process that crashed. This will be one of
  ARM-64,
  ARM,
  x86-64, or
  x86.
  Role: The task_role assigned to the process at the time of termination.
  OS Version: The OS version, including the build number, on which the crash occurred.
  Exception Information
  Not to be confused with Objective-C/C++ exceptions (though one of those may be the cause of the crash), this section lists the Mach Exception Type and related fields which provide information about the nature of the crash. Not all fields will be present in every crash report.
  Listing 5 Excerpt of the Exception Codes section from a crash report generated when a process was terminated due to an uncaught Objective-C exception.
  Listing 6 Excerpt of the Exception Codes section from a crash report generated when a process was terminated because it dereferenced a NULL pointer.
  An explanation of the fields that may appear in this section are presented below.
  Exception Codes: Processor specific information about the exception encoded into one or more 64-bit hexadecimal numbers. Typically, this field will not be present because the Crash Reporter parses the exception codes to present them as a human-readable description in the other fields.
  Exception Subtype: The human-readable name of the exception codes.
  Exception Message: Additional human-readable information extracted from the exception codes.
  Exception Note: Additional information that is not specific to one exception type. If this field contains
  SIMULATED (this is NOT a crash)then the process did not crash, but was killed at the request of the system, typically the watchdog.
  Termination Reason: Exit reason information specified when a process is terminated. Key system components, both inside and outside of a process, will terminate the process upon encountering a fatal error (e.g. a bad code signature, a missing dependent library, or accessing privacy sensitive information without the proper entitlement). macOS Sierra, iOS 10, watchOS 3, and tvOS 10 have adopted new infrastructure to record these errors, and crash reports generated by these operating systems list the error messages in the Termination Reason field.
  Triggered by Thread: The thread on which the exception originated.
  The following sections explain some of the most common exception types:
  Bad Memory Access [EXC_BAD_ACCESS // SIGSEGV // SIGBUS]
  The process attempted to access invalid memory, or it attempted to access memory in a manner not allowed by the memory's protection level (e.g. writing to read-only memory). The Exception Subtype field contains a
  kern_return_t describing error and the address of the memory that was incorrectly accessed.
  Here are some tips for debugging a bad memory access crash:
  If
  objc_msgSendor
  objc_releaseare near the top of the Backtraces for the crashed thread, the process may have attempted to message a deallocated object. You should profile the application with the Zombies instrument to better understand the conditions of this crash.
  If
  gpus_ReturnNotPermittedKillClientis near the top of the Backtraces for the crashed thread, the process was killed because it attempted to do rendering with OpenGL ES or Metal while in the background. See QA1766: How to fix OpenGL ES application crashes when moving to the background.
  Run your application with the Address Sanitizer enabled. The address sanitizer adds additional instrumentation around memory access in your compiled code. As your application runs, Xcode will alert you if memory is accessed in a way that could lead to a crash.
  Abnormal Exit [EXC_CRASH // SIGABRT]
  The process exited abnormally. The most common causes of crashes with this exception type are uncaught Objective-C/C++ exceptions and calls to
  abort().
  App Extensions will be terminated with this exception type if they take too much time to initialize (a watchdog termination). If an extension is killed due to a hang at launch, the Exception Subtype of the generated crash report will be
  LAUNCH_HANG. Because extensions do not have a
  main function, any time spent initializing occurs within static constructors and
  +load methods present in your extension and dependent libraries. You should defer as much of this work as possible.
  Trace Trap [EXC_BREAKPOINT // SIGTRAP]
  Similar to an Abnormal Exit, this exception is intended to give an attached debugger the chance to interrupt the process at a specific point in its execution. You can trigger this exception from your own code using the
  __builtin_trap() function. If no debugger is attached, the process is terminated and a crash report is generated.
  Lower-level libraries (e.g. libdispatch) will trap the process upon encountering a fatal error. Additional information about the error can be found in the Additional Diagnostic Information section of the crash report, or in the device's console.
  Swift code will terminate with this exception type if an unexpected condition is encountered at runtime such as:
  a non-optional type with a nil value
  a failed forced type conversion
  Look at the Backtraces to determine where the unexpected condition was encountered. Additional information may have also been logged to the device's console. You should modify the code at the crashing location to gracefully handle the runtime failure. For example, use Optional Binding instead of force unwrapping an optional.
  Illegal Instruction [EXC_BAD_INSTRUCTION // SIGILL]
  The process attempted to execute an illegal or undefined instruction. The process may have attempted to jump to an invalid address via a misconfigured function pointer.
  On Intel processors, the
  ud2 opcode causes an
  EXC_BAD_INSTRUCTION exception but is commonly used to trap the process for debugging purposes. Swift code on Intel processors will terminate with this exception type if an unexpected condition is encountered at runtime. See Trace Trap for details.
  Quit [SIGQUIT]
  The process was terminated at the request of another process with privileges to manage its lifetime.
  SIGQUIT does not mean that the process crashed, but it did likely misbehave in a detectable manner.
  On iOS, keyboard extensions will be quit by the host app if they take too long to load. It's unlikely that the Backtraces shown in the crash report will point to the responsible code. Most likely, some other code along the startup path for the extension has taken a long time to complete but finished before the time limit, and execution moved onto the code shown in the Backtraces when the extension was quit. You should profile the extension to better understand where most of the work during startup is occurring, and move that work to a background thread or defer it until later (after the extension has loaded).
  Killed [SIGKILL]
  The process was terminated at the request of the system. Look at the Termination Reason field to better understand the cause of the termination.
  The Termination Reason field will contain a namespace followed by a code. The following codes are specific to watchOS:
  The termination code
  0xc51bad01indicates that a watch app was terminated because it used too much CPU time while performing a background task. To address this issue, optimize the code performing the background task to be more CPU efficient, or decrease the amount of work that the app performs while running in the background.
  The termination code
  0xc51bad02indicates that a watch app was terminated because it failed to complete a background task within the allocated time. To address this issue, decrease the amount of work that the app performs while running in the background.
  The termination code
  0xc51bad03indicates that a watch app failed to complete a background task within the allocated time, and the system was sufficiently busy overall that the app may not have received much CPU time with which to perform the background task. Although an app may be able to avoid the issue by reducing the amount of work it performs in the background task,
  0xc51bad03does not indicate that the app did anything wrong. More likely, the app wasn’t able to complete its work because of overall system load.
  Guarded Resource Violation [EXC_GUARD]
  The process violated a guarded resource protection. System libraries may mark certain file descriptors as guarded, after which normal operations on those descriptors will trigger an
  EXC_GUARD exception (when it wants to operate on these file descriptors, the system uses special 'guarded' private APIs). This helps you quickly track down issues such as closing a file descriptor that had been opened by a system library. For example, if an app closes the file descriptor used to access the SQLite file backing a Core Data store, Core Data would then crash mysteriously much later on. The guard exception gets these problems noticed sooner, and thus makes them easier to debug.
  Crash reports from newer versions of iOS include human-readable details about the operation that caused the
  EXC_GUARD exception in the Exception Subtype and Exception Message fields. In crash reports from macOS or older versions of iOS, this information is encoded into the first Exception Code as a bitfield which breaks down as follows:
  [63:61] - Guard Type: The type of the guarded resource. A value of
  0x2indicates the resource is a file descriptor.
  [60:32] - Flavor: The conditions under which the violation was triggered.
  If the first
  (1 << 0)bit is set, the process attempted to invoke
  close()on a guarded file descriptor.
  If the second
  (1 << 1)bit is set, the process attempted to invoke
  dup(),
  dup2(), or
  fcntl()with the
  F_DUPFDor
  F_DUPFD_CLOEXECcommands on a guarded file descriptor.
  If the third
  (1 << 2)bit is set, the process attempted to send a guarded file descriptor via a socket.
  If the fifth
  (1 << 4)bit is set, the process attempted to write to a guarded file descriptor.
  [31:0] - File Descriptor: The guarded file descriptor that the process attempted to modify.
  Resource Limit [EXC_RESOURCE]
  The process exceeded a resource consumption limit. This is a notification from the OS that the process is using too many resources. The exact resource is listed in the Exception Subtype field. If the Exception Note field contains
  NON-FATAL CONDITION, then the process was not killed even though a crash report was generated.
  The exception subtype
  MEMORYindicates that the process has crossed a memory limit imposed by the system. This may be a precursor to termination for excess memory usage.
  The exception subtype
  WAKEUPSindicates that threads in the process are being woken up too many times per second, which forces the CPU to wake up very often and consumes battery life.
  Typically, this is caused by thread-to-thread communication (generally using
  peformSelector:onThread:or
  dispatch_async) that is unwittingly happening far more often than it should be. Because the sort of communication that triggers this exception is happening so frequently, there will usually be multiple background threads with very similar Backtraces - indicating where the communication is originating.
  Other Exception Types
  Some crash reports may contain an un-named Exception Type, which will be printed as a hexadecimal value (e.g. 00000020). If you receive one of these crash reports, look directly to the Exception Codes field for more information.
  The exception code
  0xbaaaaaadindicates that the log is a stackshot of the entire system, not a crash report. To take a stackshot, press the side button and both volume buttons simultaneously. Often these logs are accidentally created by users, andneeds the OS because it held on to a file lock or sqlite database lock during suspension. If your application is performing operations on a locked file or sqlite database at suspension time, it must request additional background execution time to complete those operations and relinquish the lock before suspending.
  The exception code
  0x2bad45ecindicates that an application has been terminated by iOS due to a security violation. The termination description "Process detected doing insecure drawing while in secure mode" indicates the app tried to draw to the screen when not permitted to do so, such as when the screen is locked. Users may not notice this termination since the screen is off or the lock screen is displayed when this termination occurs.
  Additional Diagnostic Information
  This section includes additional diagnostic information specific to the type of termination, which may include:
  Application Specific Information: framework error messages captured just before the process terminated
  Kernel Messages: details about code-signature problems
  Dyld Error Messages: error messages emitted by the dynamic linker
  Starting in macOS Sierra, iOS 10, watchOS 3, and tvOS 10, most of this information is now reported in the Termination Reason field under the Exception Information.
  You should read this section to better understand the circumstances under which the process was terminated.
  Listing 7 Excerpt of the Application Specific Information section from a crash report generated when a process was terminated because a framework it links against could not be found.
  Listing 8 Excerpt of the Application Specific Information section from a crash report generated when a process was terminated because it failed to load its initial view controller quickly.
  Backtraces
  The most interesting part of a crash report is the backtrace for each of the process's threads at the time it terminated. Each of these traces is similar to what you would see when pausing the process with the debugger.
  Listing 9 Excerpt of the Backtrace section from a fully symbolicated crash report.
  The first line lists the thread number and the identifier of the currently executing dispatch queue. The remaining lines list details about the individual stack frames in the backtrace. From left to right:
  The stack frame number. Stack frames are presented in calling order, where frame zero is the function that was executing at the time execution halted. Frame one is the function that called the function in frame zero, and so on.
  The name of the binary in which the executing function for the stack frame resides.
  For frame zero, the address of the machine instruction that was executing when execution halted. For the remaining stack frames, the address of the machine instruction that will next execute when control returns to the stack frame.
  In a symbolicated crash report, the method name for the function in the stack frame.
  Exceptions
  Exceptions in Objective-C are used to indicate programming errors detected at runtime such as accessing an array with an index that is out-of-bounds, attempts to mutate immutable objects, not implementing a required method of a protocol, or sending a message which the receiver does not recognize.
  If an exception is not caught, it is intercepted by a function called the uncaught exception handler. The default uncaught exception handler logs the exception message to the device's console then terminates the process. Only the exception backtrace is written to the generated crash report under the Last Exception Backtrace section, as shown in Listing 10. The exception message is omitted from the crash report. If you receive a crash report with a Last Exception Backtrace you should acquire the console logs from the originating device to better understand the conditions which caused the exception.
  Listing 10 Excerpt of the Last Exception Backtrace section from an unsymbolicated crash report.
  A crash log with a Last Exception Backtrace containing only hexadecimal addresses must be symbolicated to produce a usable backtrace as shown in Listing 11.
  Listing 11 Excerpt of the Last Exception Backtrace section from a symbolicated crash report. This exception was raised when loading a scene in the app's storyboard. The corresponding IBOutlet for a connection to an element in the scene was missing.
  64-bit iOS uses a "zero-cost" exception implementation. In a "zero-cost" system, every function has additional data that describes how to unwind the stack if an exception is thrown across the function. If an exception is thrown across a stack frame that has no unwind data then exception handling cannot proceed and the process halts. There might be an exception handler farther up the stack, but if there is no unwind data for a frame then there is no way to get there from the stack frame where the exception was thrown. Specifying the
  -no_compact_unwind flag means you get no unwind tables for that code, so you can not throw exceptions across those functions.
  Additionally, if you are including plain C code in your application or a library, you may need to specify the
  -funwind-tables flag to include unwind tables for all functions in that code.
  Thread State
  This section lists the thread state of the crashed thread. This is a list of registers and their values at the time execution halted. Understanding the thread state is not necessary when reading a crash report but you may be able to use this information to better understand the conditions of the crash.
  Listing 12 Excerpt of the Thread State section from a crash report from an ARM64 device.
  Binary Images
  This section lists the binary images that were loaded in the process at the time of termination.
  Listing 13 Excerpt of the application's entry in the binary images section of a crash report.
  Each line includes the following details for a single binary image:
  The binary image's address space within the process.
  The binary name or bundle identifier of the binary (macOS only). In crash reports from macOS, a (+) is prepended if the binary is part of the OS.
  (macOS only) The binary's short version string and bundle version, separated by a dash.
  (iOS only) The architecture of the binary image. A binary may contain multiple "slices", one for each architecture it supports. Only one of these slices is loaded into the process.
  An UUID which uniquely identifies the binary image. This value changes with each build of the binary and is used to locate the corresponding dSYM file when symbolicating the crash report.
  The path to the binary on disk. backtraces for the application threads. A low memory report begins with a header similar to the Header of a crash report. Following the header are a collection of fields listing system-wide memory statistics. Take note of the value for the Page Size field. The memory usage of each process in a low memory report is reported in terms of number of memory pages.
  The most important part of a low memory report is the table of processes. This table lists all running processes, including system daemons, at the time the low memory report was generated. If a process was "jettisoned", the reason will be listed under the [reason] column. A process may be jettisoned for a number of reasons:
  [per-process-limit]: The process crossed its system-imposed memory limit. Per-process limits on resident memory are established by the system for all applications. Crossing this limit makes the process eligible for termination.
  [vm-pageshortage]/[vm-thrashing]/[vm]: The process was killed due to memory pressure.
  [vnode-limit]: Too many files are open.
  [highwater]: A system daemon crossed its high water mark for memory usage.
  [jettisoned]: The process was jettisoned for some other reason.
  If you do not see a reason listed next to your app/extension process, the cause of the crash was not memory pressure. Look for a
  .crash file (described in the previous section) for more information.
  When you see a low memory crash, rather than be concerned about what part of your code was executing at the time of termination, you should investigate your memory usage patterns and your responses to low memory warnings. Locating Memory Issues in Your App.
  Related Documents
  For information about how to use the Instruments Zombies template to fix memory overrelease crashes, see Eradicating Zombies with the Zombies Trace Template.
  For more information about application archiving, refer to the the App Distribution Guide.
  For more information about interpreting crash logs, see Understanding Crash Reports on iPhone OS WWDC 2010 Session.
  Document Revision History
  Copyright © 2018 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2018-01-08