Author: davidxu
Date: Sat Sep 25 06:27:09 2010
New Revision: 213159
URL: http://svn.freebsd.org/changeset/base/213159

Log:
  Because old _pthread_cleanup_push/pop do not have frame address,
  it is incompatible with stack unwinding code, if they are invoked,
  disable stack unwinding for current thread, and when thread is
  exiting, print a warning message.

Modified:
  head/lib/libthr/thread/thr_clean.c
  head/lib/libthr/thread/thr_exit.c

Modified: head/lib/libthr/thread/thr_clean.c
==============================================================================
--- head/lib/libthr/thread/thr_clean.c  Sat Sep 25 04:58:46 2010        
(r213158)
+++ head/lib/libthr/thread/thr_clean.c  Sat Sep 25 06:27:09 2010        
(r213159)
@@ -78,12 +78,10 @@ __pthread_cleanup_pop_imp(int execute)
 void
 _pthread_cleanup_push(void (*routine) (void *), void *arg)
 {
-#ifdef _PTHREAD_FORCED_UNWIND
-       PANIC("_pthread_cleanup_push is not supported while stack unwinding is 
enabled.");
-#else
        struct pthread  *curthread = _get_curthread();
        struct pthread_cleanup *newbuf;
 
+       curthread->unwind_disabled = 1;
        if ((newbuf = (struct pthread_cleanup *)
            malloc(sizeof(struct _pthread_cleanup_info))) != NULL) {
                newbuf->routine = routine;
@@ -92,15 +90,10 @@ _pthread_cleanup_push(void (*routine) (v
                newbuf->prev = curthread->cleanup;
                curthread->cleanup = newbuf;
        }
-#endif
 }
 
 void
 _pthread_cleanup_pop(int execute)
 {
-#ifdef _PTHREAD_FORCED_UNWIND
-       PANIC("_pthread_cleanup_pop is not supported while stack unwinding is 
enabled.");
-#else
        __pthread_cleanup_pop_imp(execute);
-#endif
 }

Modified: head/lib/libthr/thread/thr_exit.c
==============================================================================
--- head/lib/libthr/thread/thr_exit.c   Sat Sep 25 04:58:46 2010        
(r213158)
+++ head/lib/libthr/thread/thr_exit.c   Sat Sep 25 06:27:09 2010        
(r213159)
@@ -51,6 +51,7 @@ static void   exit_thread(void) __dead2;
 __weak_reference(_pthread_exit, pthread_exit);
 
 #ifdef _PTHREAD_FORCED_UNWIND
+static int message_printed;
 
 static void thread_unwind(void) __dead2;
 #ifdef PIC
@@ -220,18 +221,28 @@ _pthread_exit_mask(void *status, sigset_
        /* Save the return value: */
        curthread->ret = status;
 #ifdef _PTHREAD_FORCED_UNWIND
+
 #ifdef PIC
        thread_uw_init();
+#endif /* PIC */
+
+#ifdef PIC
        if (uwl_forcedunwind != NULL) {
-               thread_unwind();
-       }
 #else
        if (_Unwind_ForcedUnwind != NULL) {
+#endif
+               if (curthread->unwind_disabled) {
+                       if (message_printed == 0) {
+                               message_printed = 1;
+                               _thread_printf(2, "Warning: old 
_pthread_cleanup_push was called, "
+                                       "stack unwinding is disabled.\n");
+                       }
+                       goto cleanup;
+               }
                thread_unwind();
-       }
-#endif /* PIC */
 
-       else {
+       } else {
+cleanup:
                while (curthread->cleanup != NULL) {
                        __pthread_cleanup_pop_imp(1);
                }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to