This question follows on from my other question on why my app isn't being brought down by exceptions.
The Problem
When an exception is thrown on the main thread via an Action, the app still doesn't crash.
As per Dave's answer to my original question, I've implemented the reportException category on NSApplication and set the uncaught exception handler.
Code
I've got the following in my app delegate, which I've hooked up to a button in my UI to test.
-(IBAction)crashOnMainThread:(id)sender {
[self performSelectorOnMainThread:@selector(crash) withObject:nil waitUntilDone:YES];
}
-(void)crash {
// To test out the exception handling
[NSException raise:NSInternalInconsistencyException format:@"This should crash the app."];
}
When I press the button, my app doesn't crash. When I look at the console log, I see this:
06/09/2010 14:12:25 EHTest1[26384] HIToolbox: ignoring exception 'This should crash the app.' that raised inside Carbon event dispatch
(
0 CoreFoundation 0x00007fff80ab4cc4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x00007fff819560f3 objc_exception_throw + 45
2 CoreFoundation 0x00007fff80ab4ae7 +[NSException raise:format:arguments:] + 103
3 CoreFoundation 0x00007fff80ab4a74 +[NSException raise:format:] + 148
4 EHTest1 0x00000001000010e3 -[EHTest1_AppDelegate crashLapsus] + 63
5 Foundation 0x00007fff88957c25 -[NSObject(NSThreadPerformAdditions) performSelector:onThread:withObject:waitUntilDone:modes:] + 234
6 Foundation 0x00007fff8896ad48 -[NSObject(NSThreadPerformAdditions) performSelectorOnMainThread:withObject:waitUntilDone:] + 143
7 EHTest1 0x0000000100001030 -[EHTest1_AppDelegate crashOnMainThread:] + 60
8 AppKit 0x00007fff85c7e152 -[NSApplication sendAction:to:from:] + 95
9 AppKit 0x00007fff85ca26be -[NSMenuItem _corePerformAction] + 365
** Snip **
It looks like Carbon is catching the exception, which is really annoying.
This suggests that for any action code, you need to immediately run it in a background thread so any exceptions are registered as uncaught. Huh? I've not seen any code that's structured like this.
What I've tried
Crashing the app with a delay so it's not connected to a UI element. It crashes fine.
I've tried installing a custom NSExceptionHandler using this in my app delegate:
-(BOOL)exceptionHandler:(NSExceptionHandler *)sender
shouldHandleException:(NSException *)exception
mask:(unsigned int)aMask {
abort();
return YES;
}
-(void)applicationWillFinishLaunching:(NSNotification *)aNotification {
NSExceptionHandler *handler = [NSExceptionHandler defaultExceptionHandler];
[handler setExceptionHandlingMask:NSLogAndHandleEveryExceptionMask];
[handler setDelegate:self];
}
the problem here is it crashes on every exception, whether it's caught or not.
If I try and check the mask and don't crash on a caught exception, I'm back to square 1 as it seems that HIToolbox catches the exception in exactly the same way as a try/catch block would.
Questions
- How can I stop HIToolbox catching the exceptions so that my app uses the uncaught exception handler and crashes?
- Is it OK to be running code that's in the same call stack as an action? Surely this is OK?
- If it's not OK, what's the alternative?
This is driving me up the wall, so any help would be much appreciated.
[NSException raise]
andobjc_exception_throw
to debug your exceptions, no need to crash there. – Decarbonize