Building Your Own Crash Report in Swift. Think Twice Before Doing It.
By: Gabriel Marson
Tags: Error Handling, Crash, Exception Handling, Swift, Crashlytics

Now it gets complicated

So what is the problem with the code above? The thing is that Swift doesn't use exceptions(objective-c does), it use Errors. And because of that, our code won’t be capable to handle any kind of the thrown errors. So it will log basically nothing.

That was the moment I realized that to build a more capable crash report, we must sweep throughout the stack trace, find the information we want and translate them to something that developers would actually understand. That’s because the data contained in the stack trace will often tell us what happened but not why it happened. And this brings us to our problems:

Your code will run on a crashed process

It is extremely unsafe and unreliable to run code in this scenario because the process is in an undefined state. Some risks could be minimized by making your code tied to system implementation details. Even so, it’s not 100% guaranteed that your code will run without problems because, if Apple decides to change something in its OS, then the crash reporter, or at least some part of it, would have to be rewritten.

Handling signals

At some point of the code, we must implement a way to handle the signals in the stack trace to catch the crash. I've found out that there are two ways of doing that:

UNIX Signals: Since there are more developers that are more familiar to Unix Signals, you will find more stuff googling about this. I suggest starting from this one, but be aware that there are some events of crash in swift that are not directly translated to UNIX Signals.

Since there are more developers that are more familiar to Unix Signals, you will find more stuff googling about this. I suggest starting from this one, but be aware that there are some events of crash in swift that are not directly translated to UNIX Signals. Mach Exception Handler: This is the default error handling mechanism used by Apple crash reporter. You might even think that using this is a good idea, but this mechanism is quite complex to understand.

We also have to be very careful about how we scan memory addresses by looking for these signals.

Reading Memory

As well pointed by this thread, we might scan a memory address that we shouldn't and end in an undefined state that will cause unexpected behavior. It’s reasonable to assume(for the sake of minimizing the risks), that our signal handler can safely access the following types of memory.

Its code

Its stack

Its arguments

Immutable global state

This caution about memory reading is important because in case something unpredicted happens, it not only will affect our own code but will also, most likely, prevent apple crash reporter from working properly.

Apple Crash Report

Like I said, it is very crucial that, by building a reading memory algorithm, we pay attention to not break Apple's own crash report. If we scan a bad memory address caused by reading a corrupted section of memory, then we must exit() our code and let the default crash reporter do the job.

And this is just one problem regarding the crash reporter. Let's not even mention that we might end up in significant privacy implications if we do not follow apple guidelines about privacy data.

Symbolication and Stack Unwinding

Let’s imagine that we managed to successfully handle all of the problems listed above. After a sweep through the stack trace we will find information that can't be understood. And why this happens? Because we will find the addresses related to crash and not a string describing what happened.

In order to get the actual function calls we need to apply Symbolication to the addresses. I forgot to mention that there are other stuff besides functions calls on the stack trace, so some filtering would have to be done. This whole process is called stack unwinding. The following image taken from this lecture illustrates quite well the hole process.

And these are not all of the problems 😞

I've listed just the ones that I thought to be more relevant. If you keep digging, it’s guaranteed that you will find more problems.