How to use the "All Exceptions" breakpoint for exceptions outside #try {} #catch {}? - objective-c

In Xcode, you can go to the Breakpoints tab, then add a breakpoint for "All Exceptions".
I find this very helpful, but is it possible for this to break the program only when the exception is not handled by a #try {} #catch {} in my code? Those are the only ones that interest me.
It would be even nicer if I could select specific files where I'm interested in using this breakpoint system, although I'm guessing that's a bit too much to ask.

The best I've found is breaking on abort; it will print the exception and backtrace in the log before breaking. You may also have luck setting your own unhandled exception handler and breaking on that.
If you really want to use All Exceptions the way you described, please file a bug with apple:
http://bugreport.apple.com

Related

Exception thrown when loading sound- but things work anyway

I have the following lines to preload a couple of (short) sounds in a sound-storing singleton (from which they can then be grabbed when need to play arises)
_successSound = [SKAction playSoundFileNamed:#"success2.wav" waitForCompletion:NO];
_failureSound = [SKAction playSoundFileNamed:#"failure2.mp3" waitForCompletion:NO];
When i run my application with an exception breakpoint (which I tend to always do), it breaks on the second line. Removing the breakpoint, everything instead works as expected. I had previously done this 'loading' only when the sound was to be played (which caused a slowdown the first time it had to be played), and it never caused any exceptions.
Edit: should also add that there aren't any exception if I change the failure2 sound to some other sound in my soundfolder- perhaps it's something to do with it being mp3?
OS code can throw exceptions that are caught and never visible to the outside, and that's inconvenient if you set a breakpoint on exceptions but nothing to worry about and not something that you need to avoid, as long as there are no uncaught exceptions.
It happens a lot with APIs that are implemented in C++ - throwing and catching exceptions is much more common in C++.
Ok, so I got rid of the exception by converting the mp3 to wav. If anyone knows why this was a problem in the first place though, I'd be very interested.

In a #try-#catch-#finally block, is it good use finally or to continue normally?

This is a simple Objective-C question.
When you use a #trythe work flow can run in 2 ways
If some NSException appear, the code immediately jump to #catch block and than to #finally
If not, finish to run the #try block and than run #finally
So, what is the difference to use or not use the #finally block? If I use only:
-(void)function{
#try {
...
}
#catch (NSException *exception) {
...
}
>>>The workflow will run this line in any case?
}
Than the rest of the function will run, or only the #catch block if a NSException is created?
"A #finally block contains code that must be executed whether an exception is thrown or not."
Does code in finally get run after a return in Objective-C?
The finally block exists to release/clean up resources like open sockets, open files, database locks, semaphore locks, and so on.
If an error occurs inside of the catch block or the catch block rethrows the exception, then the line:
>>>The workflow will run this line in any case?
is not executed. However, the code in the finally block should be executed. The finally block is the last, best chance to exit cleanly from an application that is about to crash. Even if the application is not about to crash, it is still the best place to cleanup resources because the code inside the finally block is more likely to be executed under unexpected conditions than code outside of the finally block.
A couple things to note:
The #catch block is not required, you can have #try-#finally, and
use the #finally block for anything (e.g. cleanup) that must happen
even if an exception occurs
The #catch block doesn't have to catch
NSException, it may (and probably should) be changed to catch more specific
exceptions. In that case the #catch block, along with the code below
the #try-#catch-#finally, would not be run depending on the exception
Few important points that were missed in other's answers here.
Apple does NOT recommend the use of #try #catch #finally clauses in production code. Their penalty is too high, and the real benefits are few. In C++ where defensive code is all over the place, you can design your application to be "exception based" meaning, all the code is designed for stack-rollback and throwing and rethrowing exceptions until they reach the top level of the stack. This is NOT the case in Obj-C, and even in C++ this paradigm kills most compiler optimizations, because the compiler cannot shortcut any scenario as an exception can break it in the middle.
However --- Apple provides the try/catch/finally mechanism in Obj-C, so you can create debug-configuration-only code, that will help you identify and catch (literally) your bugs BEFORE releasing the application to the public.
In addition Apple provides a complete (and beautiful) "Error handling" paradigm and protocol, backed up in API (NSError object, nested NSErrors NSError recovery protocol, NSError display API etc.) that is suitable for runtime error handling in your application - in "release" builds of your applications.
The above is correct for both iOS and MacOS-X error handling.
So, the whole discussion about the use of #finally here are a little exaggerated.

Xcode 4 exception breakpoint filtering

Breaking on Objective-C exceptions is really useful and easily the best way to debug issues with NSArray and the like. However, exceptions are also a great thing to use while actually programming.
Xcode offers two choices for breaking on Obj-C exceptions:
Break whenever an exception is thrown
Break whenever an exception is caught
Breaking on catch seems to be basically useless, since the point of #throw is a lot more important. However, if I'm handling an exception fine, I don't want my program to stop.
So, the ideal situation would be: break on all exceptions that are not caught by my code, but show a stack trace for when the exception was thrown.
Another decent solution would be some sort of debugging whitelist for exceptions that should not be broken on.
Is there any way to filter exception breakpoints?

What’s the rationale behind the Cocoa exception policy - or why use exceptions only for programmer errors?

What’s the rationale behind the Cocoa exception policy - or why use exceptions only for programmer errors?
I understand that exception used to be rather expensive so one would not want to overuse them. But that changed with the modern runtime and it’s zero-cost exceptions. I also understand that the use of exceptions to do general control flow is not a good idea because it could lead to code that is rather hard to understand.
But why should one use exceptions to signal programmer errors? For that case logging a message followed by abort() should be enough. Why should I write a #catch(...) block to handle a programmer error instead of fixing the actual mistake? I’ve been thinking about this a lot and I haven’t found any reasonable use of an exception for a programmer error.
(As a side note/question: I’ve written a recursive descent parser, and I’m planning on using exceptions in there for handling errors. Seems to be much more reasonable to me than adding an out parameter to every single function in there and manually check for an error everywhere. Of course I’ll catch any exceptions I throw in the top level methods that get called from the outside. Anyone think that’s a bad use for exceptions?)
Update: The real question
Thanks for all the answers so far. They all are true, but they don’t actually answer my question. So I guess I wasn’t really clear about it, sorry for that. So here’s the real question:
Why does Cocoa throw exceptions for programmer errors (or assertions) at all? One isn’t supposed to catch them, and actually writing code that handles a programmer error somewhere down the call stack is not a good idea anyways. Seems to me that exceptions there are a wasted effort. Simply logging the error and calling abort() (which exits the program) should be enough. So what’s the advantage there of actually having an exception thrown?
I understand why exceptions are not generally used and discouraged - most parts of Cocoa are just not exception safe. And that’s not the question here. I hope I made this clear now.
Why should I write a #catch(...) block to handle a programmer error instead of fixing the actual mistake?
In most cases, you wouldn't. In Objective-C, you generally don't handle exceptions. If an exception occurs, it causes a crash, and then you fix the bug -- hopefully you catch this during testing.
Of course, in some cases this doesn't work out. Maybe you do except an exception and you can workaround it, so you catch it. Or there's there rare API that'll throw exceptions instead of using error objects.
To be honest, I very, very rarely use try/catch in my Objective-C code.
As for the rationale, I think it's largely due to Objective-C's C heritage. Back in the early 80s when Objective-C was developed, exceptions were kind of "new" (i.e., not in many mainstream languages yet), and Objective-C catered more to the C tradition of using NULL or an out parameter to signal errors.
Your question explicitly assumes that "one isn’t supposed to catch them." This is incorrect. The programmer isn't expected to catch them under normal circumstances, but that isn't to say that they must never be caught for any purpose.
Example: I'm not sure if it does anymore since it's much less buggy these days, but I know it at least used to be the case that Xcode would catch exceptions and put up a dialog saying, "Such-and-such happened. It doesn't appear to be a critical problem, but you should probably save and restart the program to avoid any trouble in the future."
Why does Cocoa throw exceptions for
programmer errors (or assertions) at
all? One isn’t supposed to catch them,
and actually writing code that handles
a programmer error somewhere down the
call stack is not a good idea anyways
Ah!
Three reasons leap to mind.
One, if you catch an exception more or less at your main run loop you could autosave state to a temporary location, crash, and on restart have a "try to restore from just before the crash, warning: may cause another crash and you should check your data very carefully" dialog/sheet/thingie. Or even just catch the exception and tell the user to do a "Save As", quit and restart.
Two, things like the unit test framework make good use of exceptions to abort the current test (logging a failure), and continuing with the rest of the tests. This lets you see if a change you made has one regression (that happens to index a NSArray out of bounds), or if you have six regressions (one or more of which throw an exception).
Three, maybe when added to ObjC it was intended to handle many kinds of errors with exceptions, and after real world experience the useful scope was determined to be "nearly fatal errors only".
The main reason for avoiding throwing exceptions is that you may accidentally throw them through stack frames that are not exception aware. For instance, if a data source for a table view throws an exception, that is not caught and handled before the delegate method returns control to the table view, it might cause all sorts of trouble as it unwinds the table view's stack frames, side stepping various releases of temporary objects and other resources.
Having said that, I personally like exceptions and use them wherever I think they are the natural thing to do, but with the caveat of never allowing them to propagate to code that is not documented as exception aware.
There are likely a lot of reasons. The "historical reasons" others have covered is sufficient to explain the current state of affairs, but there are other possibilities.
Another possibility is Objective C is not typically a "Resource Acquisition Is Initialization" kind of language (yes this is more a library issue then a language issue, but it is real). So most Objective C code that has an error thrown through it will leave invalid program state (things still locked, over retained objects). All things you could deal with if you were thinking about it, and not all things RAII would magically fix (there is a lot of exception unsafe C++ code out there, and C++ is largely RAII).
As noted above stating that you do handle an exception is free(ish), but actually having one thrown is costly (maybe an order of magnitude or two more costly then an extra parameter and a conditional check). So if your parser (for example) uses them to signal errors in parsing, being given a document with a lot of errors can take a LOT longer to parse then if you had explicit checks for an error parameter.
Personally I like exceptions, and would prefer to throw exceptions from my libraries when things "go wrong", but that isn't the Cocoa way, so I use exceptions to handle programmer errors and an error indication and NSError** for other things. It isn't great, but it makes it so other people can use my libraries without having to learn a new way to write Objective C code.
The modern runtime does not give you zero-cost exceptions, it gives you exceptions that only incur their cost if an exception is thrown.

more detailed information about the exception in xcode

So I am trying to troubleshoot why adding an item to my dictionary causes an exception.
It turns out that I used a NSDictionary instead of NSMutableDictionary.
However the exception I saw... setobject format exception was no help at all.
Where do you look in xCode to get detailed exception information? Or is this all that is given?
It's unfortunate that the emitted stacktrace contains the memory address of the method calls on the stack rather than their names.
I recommend using the debugger and setting a breakpoint at objc_exception_throw. The debugger can tell exactly where the exception was made and what the arguments were.
markjnet provides a nice writeup on exception debugging here.