From: Roland S. <rol...@on...> - 2013-07-30 17:25:49
|
Hi... Presently I am migrating a big codebase from GCC 4.4.3 to 4.8.2 using the current trunk mingw-w64 crt and headers. I am using a self built toolchain with SEH for 64bit windows and sjlj on 32bit windows. Everything appears to be fine when compiling for 32bit. But I am/was facing some trouble when running ObjectiveC code on 64 bit windows when using ObjectiveC (GNUStep) exceptions. We are still using traditional ObjC exceptions. NS_DURING <code which can throw an excpetion> NS_HANDLER <exception handling code> NS_ENDHANDLER All these 3 NS_ constructs are macros wrapping around setjmp(). With resolved macros it looks like this: {NSHandler NSLocalHandler; _NSAddHandler(&NSLocalHandler); if (!setjmp(NSLocalHandler.jumpState)) { <code which can throw an excpetion> _NSRemoveHandler(&NSLocalHandler); } else { NSException *localException = NSLocalHandler.exception <exception handling code> } } The exception is "thrown" always from within an instance of the NSException class, which code is located in the gnustep-base dll. There the longjmp(jumpState,1) is performed. With our version of gcc 4.4.3 (which Kai knows very well ;-)) everything is fine. Not so with gcc 4.8.2 in "release" mode (without symbols). Here the resulting binary crashes (most of the times) when an exception is raised (exactly when the longjmp() is performed). After nearly loosing all of my remaining hairs in the last 3 days I found a workaround. As far as I can see in setjmp.h setjmp()/longjmp() wraps around _setjmp(jmp_buf,__builtin_frame_adress(0)) and longjmp() from msvcrt.dll. When I use gcc's __builtin_setjmp() / __builtin_longjmp() instead of the msvcrt supplied versions it works again. Has anyone seen something mad like that before? Just 2 more informations: 1. When I do a normal setjmp()/longjmp() combo manually inside of an ObjC method everything is fine too. Works as expected. I assume when I cross dll borders (setjmp() in one dll and longjmp() in another) something is going mad. I would like to understand what is going on here. 2. When I dump out the jmp_buf supplied to setjmp() and look at it it looks perfectly ok. Frameadress/Rip are correct. Even all other registers look ok. jmp_buf is also not corrupted in between of setjmp() and longjmp(). And only win64 bit is affected not 32bit. Presently I am compiling with optimization completely turned off and nearly no other gcc options enabled beside of -fno-omit-frame-pointer. Thanks for your help, Roland |