Date: Thu, 10 Sep 1998 18:13:47 +0000 (GMT) From: Terry Lambert <tlambert@primenet.com> To: smp@csn.net (Steve Passe) Cc: tlambert@primenet.com, joelh@gnu.org, obrien@NUXI.com, dfr@nlsystems.com, jb@cimlogic.com.au, current@FreeBSD.ORG Subject: Re: Compiler problems with gcc-2.7.2.1 Message-ID: <199809101813.LAA26539@usr08.primenet.com> In-Reply-To: <199809101556.JAA05124@Ilsa.StevesCafe.com> from "Steve Passe" at Sep 10, 98 09:56:29 am
next in thread | previous in thread | raw e-mail | index | archive | help
> We found that these patches only fix half the problem with 2.8.1. Note > this piece of code in libgcc2.c: > > /* We must call terminate if we try and rethrow an exception, when > there is no exception currently active and when there are no > handlers left. */ > if (! __eh_info || (*dhc) == top_elt) > ^^^^^^^ > __terminate (); > > The original patches correctly create a per-thread dynamic_handler_chain, > but the code in __sjthrow () walks off the end of the world when unwinding > the chain in a throw() attempt. This usually creates the classical > threads prog hang with the program consumming 99% of the CPU and going > nowhere, othertimes you get a segfault of other coredump. I haven't seen this. Did you enable the code in uthread_init.c and rebuild libc_r before trying this? > The specific problem is that top_elt (the original global "top of dhc") > is not in the chain with the per-thread dhc scheme, and thus never matched. It is, if you enabled the code in uthread_init.c: ============================================================================= typedef void *** (*dynamic_handler_allocator)(); extern void __set_dynamic_handler_allocator(dynamic_handler_allocator); static pthread_key_t except_head_key; typedef struct { void **__dynamic_handler_chain; void *top_elt[2]; } except_struct; static void ***dynamic_allocator_handler_fn() { except_struct *dh = (except_struct *)pthread_getspecific(except_head_key ); if(dh == NULL) { dh = (except_struct *)malloc( sizeof(except_struct) ); memset(dh, '\0', sizeof(except_struct)); dh->__dynamic_handler_chain= dh->top_elt; pthread_setspecific(except_head_key, (void *)dh); } return &dh->__dynamic_handler_chain; } ============================================================================= **** Fourth line up! ************************************************* And immediately before the final return in _thread_init(): ============================================================================= /* Create the thread-specific data for the exception linked list. */ if(pthread_key_create(&except_head_key, NULL) != 0) PANIC("Failed to create thread specific execption head"); /* Setup the gcc exception handler per thread. */ __set_dynamic_handler_allocator( dynamic_allocator_handler_fn ); ============================================================================= > This is fixed in the attached updated patch. Note that it is a QUICK hack > with little thought to "beauty", I needed to fry more important fish at > the time. More importantly, it doesn't completely fix the problem. The > part where you walk off into the weeds is gone, it properly walks back up > the stack, running all the destructors. But it doesn't seem to get back > to thecatch() statement. Instead it hits the __terminate() statement, > ignoring the catch() block. I havn't had time to figure out why, > if anyone does, please post! Subclassing classes of exceptions appears to fail, if done directly; at least, it has been my experience that attempting to recover RTTI from "throw classname()" style immediate copy-construction fails. What I normally do is something like (this is from my Exception.H from my implementation of the JAVA classes in C++): ============================================================================= class Exception { public: Exception( void) { }; virtual ~Exception( void) { }; }; Exception #ifdef _EXCEPTION_CC #define _EXCEPTION(x,y) class _ ## x : public y { \ public: \ _ ## x( void) { }; \ virtual ~_ ## x( void) { }; \ }; \ Exception *x = (Exception *)new _ ## x (); #define EXCEPTION(x,y) _EXCEPTION(x, _ ## y) #else // !EXCEPTION_CC #define _EXCEPTION(x,y) class _ ## x : public y { \ public: \ _ ## x( void) { }; \ virtual ~_ ## x( void) { }; \ }; \ extern Exception *x; #define EXCEPTION(x,y) _EXCEPTION(x, _ ## y) #endif // !EXCEPTION_CC _EXCEPTION(RuntimeException, Exception) EXCEPTION(ArithmeticException, RuntimeException) EXCEPTION(ArrayStoreException, RuntimeException) ... ============================================================================= Then in Exception.cc: ============================================================================= #define _EXCEPTION_CC 1 #include <java/lang/Exception.H> ============================================================================= Then to throw (this is from the javax/mail API implementation in C++): ============================================================================= throw MessagingException; ============================================================================= And to attempt/catch (this is from javax/mail/MessageClass): ============================================================================= bool Message::isSet( Flag flag) { Flags *flags; bool rv = false; try { flags = getFlags(); rv = flags->contains( flag); delete flags; } catch( Exception *ep) { delete flags; throw ep; // rethrow exception } return( rv); } ============================================================================= This was necessary to make the RTTI return the correct information on a class pointer that was a subclass of the Exception class. Basically, you have instanced an Exception * pointer to each instance of subclass, and then thrown these pointers instead of constructing them at runtime. What you should really try is to catch *everything* and see if what you are seeing is a failure to catch, or a catch target type mismatch. Terry Lambert terry@lambert.org --- Any opinions in this posting are my own and not those of my present or previous employers. To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199809101813.LAA26539>