This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: serious EH thread bug


> 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
--------------


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]