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>
