Global catch of exceptions

Hi to everyone reading this post.


I've got a requirement to catch all exceptions that are occuring in iOS app and log them to file and eventually send them to back-end server used by the app.


I've been reading about this topic and found one way to this but I'm not sure if it's gonna break App Store Review guideliness.


In AppDelegate I've added following:

NSSetUncaughtExceptionHandler { (exception) in
    log.error(exception.callStackSymbols.prettyPrinted())
}

signal(SIGABRT) { s in
    log.error(Thread.callStackSymbols.prettyPrinted())
    exit(s)
}

signal(SIGILL) { s in
    log.error(Thread.callStackSymbols.prettyPrinted())
    exit(s)
}

signal(SIGSEGV) { s in
    log.error(Thread.callStackSymbols.prettyPrinted())
    exit(s)
}


And then when something like this occurs it should catch that error, log it to file and exit the app with signal code that is received.


Questions:

  • Is this good approach at all?
  • Will it break App Store Review guidelines because of usage of exit()? Is it better to use kill(getpid(), SIGKILL) instead?
  • callStackSymbols are not symbolicated, is there a way to symbolicate callStackSymbols?

Accepted Reply

Before we start I’d like you to take look at my shiny new Implementing Your Own Crash Reporter post. I’ve been meaning to write this up for a while, and your question has give me a good excuse to allocate the time.

You wrote:

I've got a requirement to catch all exceptions that are occuring in iOS app and log them to file and eventually send them to back-end server used by the app.

I strongly recommend against doing this. My Implementing Your Own Crash Reporter post explains why this is so hard. It also has some suggestions for how to avoid problems, but ultimately there’s no way to implement a third-party crash reporter that’s reliable, binary compatible, and sufficient to debug complex problems

With that out of the way, let’s look at your specific questions:

Is this good approach at all?

No. The issue is that your minimalist crash reporter will disrupt the behaviour of the Apple crash reporter. The above-mentioned post discusses this problem in gory detail.

Will it break App Store Review guidelines because of usage of

exit()
?

No. iOS’s prohibition against calling

exit
is all about the normal operation of your app. If your app is crashing anyway, calling
exit
isn’t a problem.

However, calling

exit
will exacerbate the problem I covered in the previous point.

Is it better to use

kill(getpid(), SIGKILL)
instead?

That won’t improve things substantially.

callStackSymbols
are not symbolicated, is there a way to symbolicate
callStackSymbols
?

No. On-device symbolication is extremely tricky and should be avoided. Again, I go into this in detail in the post referenced above.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

Before we start I’d like you to take look at my shiny new Implementing Your Own Crash Reporter post. I’ve been meaning to write this up for a while, and your question has give me a good excuse to allocate the time.

You wrote:

I've got a requirement to catch all exceptions that are occuring in iOS app and log them to file and eventually send them to back-end server used by the app.

I strongly recommend against doing this. My Implementing Your Own Crash Reporter post explains why this is so hard. It also has some suggestions for how to avoid problems, but ultimately there’s no way to implement a third-party crash reporter that’s reliable, binary compatible, and sufficient to debug complex problems

With that out of the way, let’s look at your specific questions:

Is this good approach at all?

No. The issue is that your minimalist crash reporter will disrupt the behaviour of the Apple crash reporter. The above-mentioned post discusses this problem in gory detail.

Will it break App Store Review guidelines because of usage of

exit()
?

No. iOS’s prohibition against calling

exit
is all about the normal operation of your app. If your app is crashing anyway, calling
exit
isn’t a problem.

However, calling

exit
will exacerbate the problem I covered in the previous point.

Is it better to use

kill(getpid(), SIGKILL)
instead?

That won’t improve things substantially.

callStackSymbols
are not symbolicated, is there a way to symbolicate
callStackSymbols
?

No. On-device symbolication is extremely tricky and should be avoided. Again, I go into this in detail in the post referenced above.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you a lot for your time spent into writing this great post which really explains a lot. It gives us a lot of details where we should pay attention and also I learned at least small part of how all of it actually works. This is definitely something that should be taken with care as I already experienced with my code that was supposed to be fairly minimal crash logger.


I posted same question on Stack Overflow and got similar responses, although most of people recommend if something like this is required at least take framework that more tested and don't do it by yourself. I have shared your answer on Stack Overflow and pointed to this thread and post you made. It will definitely help others as well.


Once more, thanks a lot!


Best regards,

Najdan Tomić