51

Excuse my ignorance, but something's been bugging me about the Xcode debugger when running iPhone applications in the iPhone Simulator.

Sometimes, when I mess something up in Interface Builder, I get an unhandled exception at runtime and I get thrown back to Xcode. The only thing I see is a single line "uncaught exception" or something like that. From what I can see, there's no additional information, let alone a stack trace or anything else that's useful.

I have been developing in Visual Studio for the last decade or so, and I'm used to getting a nice stack trace and complete exception info when something like that happens.

I'm sure I'm simply missing something very obvious... Hopefully...

Philippe Leybaert
  • 168,566
  • 31
  • 210
  • 223

4 Answers4

74

If you add two breakpoints, you should be able to debug these exceptions. To do this, go to Run | Show | Breakpoints and create two global breakpoints (I do them globally because they are so useful in all my applications). The first should be named "objc_exception_throw" and its location should be "libobjc.A.dylib". The second should be "-[NSException raise]" and its location should be "CoreFoundation".

Now, if you start debugging your application with breakpoints enabled, it should break on the throw of these exceptions. You should then be able to see the chain of events that led to the exception within the debugger.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
  • 1
    For iPhone development you only need the first one. This is the best way to get details about where exceptions occur. – Kendall Helmstetter Gelner Jul 07 '09 at 19:51
  • Yes, I think the second only applies to Mac OS versions earlier than Leopard. It doesn't hurt to keep it around, though. – Brad Larson Jul 07 '09 at 20:30
  • 1
    @Kendall Helmstetter Gelner @Philippe Leybaert Is this answer still valid in xCode 4 ? I can't find libobjc.A.dylib. I mean, it is also not clear to me how to apply a breakpoint to a file (and not a line of code ?) – aneuryzm May 11 '11 at 07:55
  • 53
    @Patrick - Xcode 4 makes this even simpler. Go to the breakpoints navigator in the left pane and click the plus button at the bottom of the screen. Choose Add Exception Breakpoint... and in the bubble that pops up choose Objective-C in the Exception field. This should set a breakpoint on all exceptions being thrown. – Brad Larson May 11 '11 at 15:15
  • 1
    cool thanks. Is there a way to automatically set it for all projects ? – aneuryzm May 11 '11 at 15:29
  • 5
    With Xcode 4, if you want to make the breakpoint have a global scope, and not limited to the project you created it in, then control-click the breakpoint, and use Move, to move it to the User scope. – mahboudz Dec 24 '12 at 06:44
  • Yes, but this will catch *all* thrown exceptions, including handled ones. There's no "catch *unhandled* exceptions" mechanism in XCode as far as I can tell (the closest you can do is register some handler methods for exceptions and signals but it's not the same thing). – Ohad Schneider Dec 06 '16 at 18:12
3

The lack of a stack trace is usually indicative of a problem with LLDB (debugger). I love LLDB, but when it comes to showing stack traces and breaking on the exception rather than main in iOS apps, it's a pain in the ass and has been for a few releases now. No idea why Apple hasn't addressed this yet. To fix it is a two-step process:

  1. Edit your current scheme and under the "Run" tab change the debugger from LLDB to GDB.
  2. Go to https://developer.apple.com/bugreporter/ and report the bug so Apple addresses it.
memmons
  • 40,222
  • 21
  • 149
  • 183
2

Hey activa - for more information about runtime exceptions, you should be able to open the debugger console and see more information. I assume you've already done that, but just in case - you can get to it by selecting Run -> Console from the menu. I'm not sure why it doesn't come up automatically!

Ben Gotow
  • 14,805
  • 3
  • 42
  • 47
  • Haven't done that, thanks for the heads up. I'm still learning Xcode (it's quite a jump when you're practically living inside Visual Studio every day of your life) – Philippe Leybaert Jul 07 '09 at 18:59
  • Yeah - it's quite a change. I used Eclipse for ages, and the interface looks totally bare in comparison! Only like 5 buttons?! It's got a lot of hidden features, though. Eclipse seems so big and clunky to me now... – Ben Gotow Jul 07 '09 at 20:44
1

You can wrap your UIApplicationMain in a try/catch:

int main(int argc, char *argv[]) {
    int retVal;
    NSAutoreleasePool * pool;
    @try
    {
    pool = [[NSAutoreleasePool alloc] init];
    retVal = UIApplicationMain(argc, argv, nil, nil);
    }
    @catch(NSException* e)
    {
        NSLog(@"%@", e.reason);
    }
    @finally
    {
    [pool release];
    }
    return retVal;
}

You should also look up into setting an assertion handler while debugging: NSAssertionHandler.

Update: and also the unhandled exception handler: NSSetUncaughtExceptionHandler

Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569