Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS : Background Thread Exceptions Not Crashing

I have not found documentation that is consistent with my experience.

What I want is a good way of handling Uncaught-Exceptions in a background thread. This "way" should let the app crash, but perform some very basic operations before crashing (e.g. saving a value to UserDefaults so that it can be examined on next startup; plus logging).

On the main thread, I just set up an uncaughtExceptionHanlder and this works fine. However, on a background thread - executed as an NSOperation on an NSOperationQueue - any exception is occurring but not exiting the app: Crashing. The app continues to run in a corrupted state.

However, the Threading Programming Guide states:

Setting Up an Exception Handler If your application catches and handles exceptions, your thread code should be prepared to catch any exceptions that might occur. Although it is best to handle exceptions at the point where they might occur, failure to catch a thrown exception in a thread causes your application to exit. Installing a final try/catch in your thread entry routine allows you to catch any unknown exceptions and provide an appropriate response.

One method that does work (below) is embedding the thread-calling method with try/catch and in the case of an exception, logging and then calling abort(). But this can't be the best way of doing this. I would like to send the exception to the main thread and have it be handled by the uncaught-exception handler. Has anyone done this?

- (void)threadMethod
{
    @try
    {
        NSArray* aTest = [NSArray array];
        [aTest objectAtIndex:10];
    }
    @catch (NSException* e)
    {
        // Save to state to User Defaults.
        // Log any needed info.

        abort();
    }
    @finally
    {

    }
}

FYI: I'm running on iOS6, with XCode 4.5 SDK.

like image 925
paiego Avatar asked Jan 12 '13 22:01

paiego


1 Answers

  1. Threads run by NSOperationQueue are being managed by libdispatch, which traps exceptions and calls terminate, exiting the app. If you're seeing different behavior, you're already doing something wrong.
  2. Saving data to NSUserDefaults after an exception is an iffy proposition; because Cocoa only treats exceptions as programmer error, it doesn't make any attempt to leave itself in a usable state once one's been thrown. In short, you should be treating it the same was as you would a "real" crash, as if only async-signal-safe APIs are available. Anything Objective-C is automatically out in this regard.
  3. Your question suggests you're trying to do crash reporting. I would recommend a crash reporting solution for the purpose, such as PLCrashReporter. There are also a number of analysis and distribution services which embed crash reporting, including HockeyApp, Crashlytics, TestFlight, and QuincyKit. There are others as well, and which one is appropriate for you depends on your needs. All of them will deal with all the tricky issues involved in handling crashes and exceptions safely and saving the data for later without you having to worry about any of it.
like image 52
Gwynne Raskind Avatar answered Sep 25 '22 04:09

Gwynne Raskind