This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: serious EH thread bug
- To: jason at cygnus dot com, tot at trema dot com
- Subject: Re: serious EH thread bug
- From: mrs at wrs dot com (Mike Stump)
- Date: Fri, 20 Nov 1998 15:08:50 -0800
- Cc: egcs-patches at cygnus dot com, egcs at cygnus dot com
> From: Jason Merrill <jason@cygnus.com>
> Date: 20 Nov 1998 02:17:42 -0800
> Mike, do you have a response now?
Yes: (This should go into 1.1.1 or 1.1.2, it is critical, further this
is so nasty that any people using SJ MT EH should seriously consider
putting it in their compiler.)
Fri Nov 20 14:29:22 1998 Mike Stump <mrs@wrs.com>
* libgcc2.c (top_elt): Remove top_elt, it isn't thread safe.
The strategy we now use is to pre allocate the top_elt along
with the EH context so that each thread has its own top_elt.
This is necessary as the dynmanic cleanup chain is used on the
top element of the stack and each thread MUST have its own.
(eh_context_static): Likewise.
(new_eh_context): Likewise.
(__sjthrow): Likewise.
Doing diffs in .:
*** ./libgcc2.c.~1~ Mon Nov 16 16:00:40 1998
--- ./libgcc2.c Fri Nov 20 14:57:09 1998
*************** __empty ()
*** 3067,3076 ****
#include <stdio.h>
#endif
- /* This is a safeguard for dynamic handler chain. */
-
- static void *top_elt[2];
-
/* Allocate and return a new EH context structure. */
extern void __throw ();
--- 3067,3072 ----
*************** extern void __throw ();
*** 3078,3092 ****
static void *
new_eh_context ()
{
! struct eh_context *eh = (struct eh_context *) malloc (sizeof *eh);
! if (! eh)
__terminate ();
! memset (eh, 0, sizeof *eh);
! eh->dynamic_handler_chain = top_elt;
! return eh;
}
#if __GTHREADS
--- 3074,3099 ----
static void *
new_eh_context ()
{
! struct eh_full_context {
! struct eh_context c;
! void *top_elt[2];
! } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
!
! if (! ehfc)
__terminate ();
! memset (ehfc, 0, sizeof *ehfc);
! ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
! /* This should optimize out entirely. This should always be true,
! but just in case it ever isn't, don't allow bogus code to be
! generated. */
!
! if ((void*)(&ehfc->c) != (void*)ehfc)
! __terminate ();
!
! return &ehfc->c;
}
#if __GTHREADS
*************** eh_context_static ()
*** 3180,3185 ****
--- 3187,3194 ----
{
static struct eh_context eh;
static int initialized;
+ static void *top_elt[2];
+
if (! initialized)
{
initialized = 1;
*************** __sjthrow ()
*** 3290,3296 ****
/* 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 ();
/* Find the jmpbuf associated with the top element of the dynamic
--- 3299,3305 ----
/* 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)[0] == 0)
__terminate ();
/* Find the jmpbuf associated with the top element of the dynamic
--------------