Obj-C Exceptions In Gecko
Turns out that Objective-C exceptions and XPCOM don't interact very well.
See bug 163260.
This page is written for the people doing the original wrapping implementation for now.
The basic problem we have is that almost every call into Apple's framework (C or Obj-C) could potentially throw an Obj-C exception and unwind our stack with nasty consequences. Sometimes the browser crashes, sometimes it just appears to have lost its mind, and theoretically there could be security consequences. This is because we have no handlers in place now and as the stack unwinds code gets skipped and C++ temporary objects do not get their destructors run.
You can read more about it in the bug, but the conclusion we came to is that we need to wrap all calls into Apple frameworks with Obj-C exception handlers.
I have checked in a set of macros for doing that, see this file:
mozilla/xpcom/base/nsObjCExceptions.h
Before you start doing anything, please read through every line of that file and make sure you understand what all of it is for. If you don't understand anything please ask me on email or irc. It wouldn't be very awesome if you posted a bunch of work and had to do it all over again.
Another thing to read over is nsAppShell.mm. I have done the work for nsAppShell.mm already and checked it in. Make sure you understand why I made the choices I did there, and again ask if you are unclear about anything.
When wrapping calls in a method, the first choice you'll have to make is whether to wrap specific calls or the whole method impl. Which one you pick is usually a matter of cleanliness. If there is a big method with a single Apple framework call in it, you might just want to wrap that specific call. Your choice of macros are these:
NS_OBJC_TRY_IGNORE NS_OBJC_TRY_ABORT
NS_OBJC_TRY_EXPR_NULL NS_OBJC_TRY_EXPR_ABORT
The ones that contain EXPR are for expressions - for example:
foo = NS_OBJC_TRY_EXPR_ABORT([bar doSomething]);
They wrap an expression that returns a value. The other macros don't. They'd be for something like this:
NS_OBJC_TRY_ABORT([bar doSomething]);
The macros that include ABORT will kill the app if they catch an exception, you will almost always want to use these. It saves a lot of time if we don't have to think about recovery strategies for calls. In order to code for recovery you'd have to understand something about the context of the code you are working in. If we start seeing exceptions killing the app it'll be easy to go back and code the calls that are throwing for recovery. That probably won't happen and if it does it'll probably be just 1-2 calls we need to not abort on.
More coming... - block macros - identifying apple framework calls - non-.mm files - whitespace - including nsObjCExceptions.h
-Josh Aas