The new app update just went live on the AppStore. Everything looked perfect, so you decided to leave early and celebrate your victory.

Suddenly, your phone rings…

“Hey, we are getting a lot of angry emails! There is a major crash happening! Our users are leaving!”

Sounds familiar?

Most app developers understand how crashes negatively impact their apps. They want to keep the number of crashes as low as possible. Otherwise, they risk losing users. Unfortunately, app crashes are a fact of life in app development.

A tool like Apteligent helps you monitor for app crashes and provides valuable reports when they occur. A crash report gives detailed information of your app state at the time of the crash. It helps you understand the source of crash, which is key to fixing your bug.

Let’s walk through a sample stack trace and learn what information you can get from it.

Breaking Down the Crash Report

1 Crash Name

Crash name is the name of the exception that caused the crash. In our sample crash report, the crash was caused by SIGSEGV signal.

In POSIX-compliant operating systems, a signal is a notification sent to a process or thread to notify when an event occurs. SIGSEGV signal, or better known as segmentation fault, happens when a program tries to access an invalid memory location.

The following example is going to cause a SIGSEGV crash:

int * myNullPointer = NULL;
*myNullPointer = 42;

An invalid memory access can happen for a variety of reasons, but most often occurs while dereferencing a NULL pointer, attempting to write to read-only memory addresses, or using previously deallocated memory.

2 Crash Reason

This field describes why the crash happens. In this case, SEGV_MAPERR is the reason why the SIGSEGV signal was fired.

“SEGV_MAPERR happens when a page was accessed that is not even mapped into the address space of the application at all. This will often result from dereferencing a null pointer or a pointer that was corrupted with a small integer value.” [1]

3 App Version

App version tells you in which version the app has been crashing. On iOS, we are getting the additional build version. This information should match your Xcode project settings.

In our example, the crashed app version 1.2 and the build number is 10.

Tip: It is important to tag your code whenever you release a new version. This will help you to quickly check your code for certain app version.

Git command to tag your release:

git tag <tagname> -m “YOUR COMMIT MESSAGE HERE”
git push origin --tags

Git command to get specific tag:

git checkout <tagname>

4 Symbolicated Yes/No

Symbolicated Yes‘ indicates that Apteligent was able to symbolicate your stack trace.

Symbolication is the process of translating stack traces into a human-readable form by mapping hexadecimal addresses to function names and line numbers using symbol file(s). Apteligent automatically symbolicates crashes once you have uploaded your app’s symbol file(s) to provide more insight about the crash.

dSYM UUID is another interesting piece of information. Each build of an app/framework has an UUID, which uniquely identifies the binary. UUID is used to locate the corresponding dSYM file for symbolication.

Our documentation page has a great write up about iOS symbol files (dSYMs) and how to upload them to our server.

5 Stack Trace

Stack trace is the most interesting part of your crash report. When symbolicated, it often gives you enough information to fix your crash. A stack trace is presented in bottom-up fashion. The deepest method in the call stack is at the top.

For example, the method [CRErrorViewController updateDirtyRectangle:] on stack trace line 0 is called by [CRErrorViewController updateErrorDashboardView:] on line 1. Similarly [CRErrorViewController updateErrorDashboardView:] on line 1 was called by  [CRErrorViewController refreshErrorViews:] on line 2.

Each line of a stack trace contains some binary name, class name, function name, and line number.

Binary name indicates which app or framework the code resides in. In this example, line 0 to 2 happens in the TestApp code base, whereas line 3 to 11 happens in Apple’s UIKit code base.

Class name and method name tell you which class and function the code belongs to.

File name and line number are self-explanatory. They tell you specifically where the code is written.

Any symbolication tool can only give you these details if the app developer provides debug symbol information in the form of a dSYM. Since Apple does not ship full debug symbol information for the UIKit framework, you will only see partial symbolication for system libraries. Typically, the framework function name should give enough of an idea of what is going on.

Fixing the Bug

Apteligent shows the crashed thread and also highlights the suspect crash line in red. Suspect crash line is where we think the crash happens. In the sample crash report, Apteligent thinks the crash happens in CRErrorViewController class, updateDirtyRectangle function. Particularly, the crash happens on line 157 in file CRErrorViewController.m

Let’s check out the code on our suspect crash line.

Apparently we are trying to dereference a null pointer on line 157. Recall that, based on the crash name and crash reason, we hypothesized that the crash was caused by illegal access to certain memory address. This matches the SIGSEGV signal we are getting in the crash report.

With this information in hand, we should be able to fix the crash!

Crash reporting is one of many cool features that Apteligent provides. Check out our blog to learn more. You could also ping us if you have any questions @apteligent.

[1] StackOverflow: What is SEGV_MAPERR?