Xcode 4.2 debug doesn't symbolicate stack call

cekisakurek picture cekisakurek · Oct 20, 2011 · Viewed 41.2k times · Source

I have a problem with Xcode 4.2 debugging in an iOS 5 simulator/device. The following code crashes, as expected:

NSArray *arr=[NSArray array];
[arr objectAtIndex:100];

In iOS 4, I get a useful stack trace of hex numbers. But in iOS 5, it just gives me:

*** First throw call stack:
(0x16b4052 0x1845d0a 0x16a0674 0x294c 0x6f89d6 0x6f98a6 0x708743 0x7091f8 0x7fcaa9 0x2257fa9 0x16881c5 0x15ed022 0x15eb90a 0x15eadb4 0x15eaccb 0x6f02a7 0x6faa93 0x2889 0x2805)

Thanks.

Answer

Zane Claes picture Zane Claes · Oct 26, 2011

Nothing I tried would fix this (tried both compilers, both debuggers, etc.) After upgrading XCode for the iOS 5 update, no stack traces seemed to work.

However, I have found an effective work-around - creating my own exception handler (which is also useful for other reasons). First, create a function that will handle the error and output it to the console (as well as whatever else you want to do with it):

void uncaughtExceptionHandler(NSException *exception) {
    NSLog(@"CRASH: %@", exception);
    NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
    // Internal error reporting
}

Next, add the exception handler to your app delegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{   
    NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
    // Normal launch stuff
}

That's it!

If this doesn't work, then there are only two possible reasons:

  1. Something is overwriting your NSSetUncaughtExceptionHandler call (there can be only one handler for your entire app). For example, some 3rd party libraries set their own uncaughtExceptionHandler. So, try setting it at the END of your didFinishLaunchingWithOptions function (or selectively disabling 3rd party libraries). Or better yet, set a symbolic break point on NSSetUncaughtExceptionHandler to quickly see who is calling it. What you may want to do is to modify your current one rather than adding another one.
  2. You're not actually encountering an exception (for example, EXC_BAD_ACCESS is not an exception; credit to @Erik B's comments, below)