libobjc: Add objc-exception.h, tidy up exception handling

Nicola Pero nicola.pero@meta-innovation.com
Wed Sep 8 00:19:00 GMT 2010


In attach a proposed libobjc patch which:

 * adds the header <objc/objc-exception.h>

 * documents objc_exception_throw() in the header

 * implements and documents objc_set_uncaught_exception_handler() and objc_set_exception_matcher(), the GNU runtime equivalents of the Apple runtime objc_setUncaughtExceptionHandler() and objc_setExceptionMatcher()

 * deprecates the existing _objc_unexpected_exception hook (but leaves it in place for now)

 * modifies the GNU runtime standard exception matcher not to crash on a nil exception object

 * adds testcases for the changes

(the patch seems to work and causes no ObjC regressions)

A couple of general comments:

 * I'd like to suggest that general API compatibility with the Apple runtime is a good thing and we want to slowly reduce incompatibilities to ease porting applications to the GNU runtime.  In particular, I'd like to put functions and definitions in the same headers as they are in the Apple runtime, and while I want to keep the traditional GNU runtime naming convention, I suggest that when feasible we add to our headers preprocessor #defines that allow Apple-runtime code to be compiled and run with no changes on the GNU runtime - for example in today's patch I added

  #define objc_setUncaughtExceptionHandler objc_set_uncaught_exception_handler

so any code written for the Apple runtime that #import <objc/objc-exception.h> and uses objc_setUncaughtExceptionHandler() will run with no changes on the GNU runtime.  Is it a good plan to slowly do this for the public API to have it converge with the Apple one ?

 * I had this problem of what to do about

 @throw nil;

(obviously this most likely happens because you do @throw object; where object was dynamically created somehow and due to some bug it actually is nil instead of a valid object)  Without/before this patch, that causes a segmentation fault.  I managed to also try on an Apple OS X 10.5 machine and got a similar "illegal instruction" in there as well with the Apple runtime/Foundation.  To fix it, we have to define what we want to happen when a 'nil' exception object is thrown.  I thought about it a lot and decided that the solution I liked the most was to throw the exception normally; the exception matcher will then decide which @catch() should catch it (if any; if none does, the program will abort).  The default exception matcher will let a 'nil' exception be caught by any catch-all @catch().  My reasoning is that exception are supposed to be used when something really unexpected is happening.  Throwing an exception were the exception object is itself nil suggests things got really really wrong/unexpected.  So I do want to throw an exception upon encountering "@throw nil"; I don't think doing nothing would be a good idea.  But because we have no information on the exception (since it's nil), it seems that a catch-all @catch() is the best place where to send it; presumably the programmer added it as a last resort safeguard and is prepared to deal with very very unexpected exceptions/conditions in there.  If there is no catch-all @catch(), the program will abort, but that sounds reasonable as we'll at least execute the uncaught exception handler.  I also like this implemenation as it behaves well in terms of making sure that all @finally, uncaught exception handlers etc. are called ordinately.  And a catch-all can be used to catch even desperate situations such as a nil exception being thrown.  All certainly better than a segmentation fault inside the exception handler itself! ;-)

Comments are welcome (in particular on the Apple runtime compatibility).  I know I'm piling up quite a few uncommitted libobjc patches, but I want to get feedback early.

Thanks
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch
Type: application/octet-stream
Size: 16934 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20100908/00b2a1b1/attachment.obj>


More information about the Gcc-patches mailing list