Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Sep 1998 09:56:29 -0600
From:      Steve Passe <smp@csn.net>
To:        Terry Lambert <tlambert@primenet.com>
Cc:        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:  <199809101556.JAA05124@Ilsa.StevesCafe.com>
In-Reply-To: Your message of "Thu, 10 Sep 1998 01:25:05 -0000." <199809100125.SAA13902@usr02.primenet.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
Hi,

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.

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


--------------------------------- cut -----------------------------------
*** libgcc2.c.orig	Wed Aug 26 16:43:09 1998
--- libgcc2.c		Wed Aug 26 17:22:50 1998
***************
*** 3192,3197 ****
--- 3192,3247 ----
  static void *top_elt[2];
  void **__dynamic_handler_chain = top_elt;
  
+ #define MAKE_THREAD_SAFE
+ #ifdef MAKE_THREAD_SAFE
+ 
+ /*
+  * Jeremy Allison's patch, from mail from somewhere...
+  * smp: additional patches to make test against top_elt work properly.
+  */
+ 
+ typedef void *** (*dynamic_handler_allocator)();
+ static dynamic_handler_allocator dah = 0;
+ 
+ void __set_dynamic_handler_allocator( dynamic_handler_allocator new_dah )
+ {
+   dah = new_dah;
+ }
+ 
+ /* Routine to get the head of the current thread's dynamic handler chain
+    use for exception handling. */
+ 
+ void ***
+ __get_dynamic_handler_chain ()
+ {
+   if (dah == 0)
+     return (&__dynamic_handler_chain);
+ 
+   return (*dah)();
+ }
+ 
+ typedef void ** (*top_elt_addr)();
+ static top_elt_addr tea = 0;
+ 
+ void __set_top_elt_addr( top_elt_addr new_tea )
+ {
+   tea = new_tea;
+ }
+ 
+ /* Routine to get the per-thread top_elt address. */
+ 
+ void **
+ __get_top_elt_addr ()
+ {
+   if (tea == 0)
+     return (top_elt);
+ 
+   return (*tea)();
+ }
+ 
+ 
+ #else /* MAKE_THREAD_SAFE */
+ 
  /* Routine to get the head of the current thread's dynamic handler chain
     use for exception handling.
  
***************
*** 3203,3208 ****
--- 3253,3260 ----
    return &__dynamic_handler_chain;
  }
  
+ #endif /* MAKE_THREAD_SAFE */
+ 
  /* This is used to throw an exception when the setjmp/longjmp codegen
     method is used for exception handling.
  
***************
*** 3216,3221 ****
--- 3268,3276 ----
  __sjthrow ()
  {
    void ***dhc = __get_dynamic_handler_chain ();
+ #ifdef MAKE_THREAD_SAFE
+   void **ate = __get_top_elt_addr ();
+ #endif /* MAKE_THREAD_SAFE */
    void *jmpbuf;
    void (*func)(void *, int);
    void *arg;
***************
*** 3263,3269 ****
--- 3318,3328 ----
    /* 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.  */
+ #ifdef MAKE_THREAD_SAFE
+   if (! __eh_info || (*dhc) == ate)
+ #else
    if (! __eh_info || (*dhc) == top_elt)
+ #endif /* MAKE_THREAD_SAFE */
      __terminate ();
      
    /* Find the jmpbuf associated with the top element of the dynamic
--------------------------------- cut -----------------------------------

--
Steve Passe	| powered by 
smp@csn.net	|            Symmetric MultiProcessor FreeBSD





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?199809101556.JAA05124>