[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: tst-basic3 failing



Ulrich Drepper writes:

> Paul Mackerras wrote:
> >  It calls
> > pthread_exit, which calls __do_cancel, which calls __libc_longjmp on
> > self->cancelbuf.  The cancelbuf field gets initialized in
> > start_thread, but of course the initial thread doesn't call
> > start_thread.
> 
> If you just would have looked through the archive of the list you would
> have seen that I answered this question already a couple of times.  The
> main thread's buffer is initialized in __libc_start_main.

Ahhh - the problem is that PPC uses a different libc-start.c, and the
PPC version hasn't been updated to do the setjmp.

I merged the new bits from the generic version into the PPC version.
The patch below shows the changes.  With this patch, tst-basic3
passes.  Franz, how does this patch look to you?

Paul.

diff -urN cvs/libc/sysdeps/powerpc/elf/libc-start.c libc/sysdeps/powerpc/elf/libc-start.c
--- cvs/libc/sysdeps/powerpc/elf/libc-start.c	2003-02-26 11:47:46.000000000 +1100
+++ libc/sysdeps/powerpc/elf/libc-start.c	2003-03-12 10:11:14.000000000 +1100
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998,2000,2001,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1998,2000,2001,2002,2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -17,6 +17,7 @@
    02111-1307 USA.  */
 
 #include <stdlib.h>
+#include <stdio.h>
 #include <unistd.h>
 #include <ldsodefs.h>
 #include <bp-start.h>
@@ -30,8 +31,9 @@
 extern int __libc_multiple_libcs;
 extern void *__libc_stack_end;
 
+#include <tls.h>
 #ifndef SHARED
-# include <tls.h>
+# include <dl-osinfo.h>
 extern void __pthread_initialize_minimal (void)
 # if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
      __attribute__ ((weak))
@@ -39,6 +41,11 @@
      ;
 #endif
 
+#ifdef HAVE_PTR_NTHREADS
+/* We need atomic operations.  */
+# include <atomic.h>
+#endif
+
 struct startup_info
 {
   void *__unbounded sda_base;
@@ -83,14 +90,15 @@
 # define argv ubp_av
 #endif
 
-#ifndef SHARED
+  /* Result of the 'main' function.  */
+  int result;
+
   /* The next variable is only here to work around a bug in gcc <= 2.7.2.2.
      If the address would be taken inside the expression the optimizer
      would try to be too smart and throws it away.  Grrr.  */
   int *dummy_addr = &_dl_starting_up;
 
   __libc_multiple_libcs = dummy_addr && !_dl_starting_up;
-#endif
 
   /* the PPC SVR4 ABI says that the top thing on the stack will
      be a NULL pointer, so if not we assume that we're being called
@@ -137,6 +145,7 @@
       DL_SYSDEP_OSCHECK (__libc_fatal);
     }
 # endif
+
   /* Initialize the thread library at least a bit since the libgcc
      functions are using thread functions if these are available and
      we need to setup errno.  If there is no thread library and we
@@ -156,15 +165,15 @@
 #endif
 
   /* Register the destructor of the dynamic linker if there is any.  */
-  if (rtld_fini != NULL)
+  if (__builtin_expect (rtld_fini != NULL, 1))
     __cxa_atexit ((void (*) (void *)) rtld_fini, NULL, NULL);
 
-  /* Call the initializer of the libc.  */
-#ifdef SHARED
-  if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
-    _dl_debug_printf ("\ninitialize libc\n\n");
-#endif
+  /* Call the initializer of the libc.  This is only needed here if we
+     are compiling for the static library in which case we haven't
+     run the constructors in `_dl_start_user'.  */
+#ifndef SHARED
   __libc_init_first (argc, argv, __environ);
+#endif
 
   /* Register the destructor of the program, if any.  */
   if (stinfo->fini)
@@ -183,5 +192,34 @@
     _dl_debug_printf ("\ntransferring control: %s\n\n", argv[0]);
 #endif
 
-  exit (stinfo->main (argc, argv, __environ, auxvec));
+#ifdef HAVE_CANCELBUF
+  if (setjmp (THREAD_SELF->cancelbuf) == 0)
+#endif
+    {
+      /* XXX This is where the try/finally handling must be used.  */
+
+      result = stinfo->main (argc, argv, __environ, auxvec);
+    }
+#ifdef HAVE_CANCELBUF
+  else
+    {
+# ifdef HAVE_PTR_NTHREADS
+      /* One less thread.  Decrement the counter.  If it is zero we
+	 terminate the entire process.  */
+      result = 0;
+#  ifdef SHARED
+      int *const ptr = __libc_pthread_functions.ptr_nthreads;
+#  else
+      extern int __nptl_nthreads __attribute ((weak));
+      int *const ptr = &__nptl_nthreads;
+#  endif
+
+      if (! atomic_decrement_and_test (ptr))
+# endif
+	/* Not much left to do but to exit the thread, not the process.  */
+	__exit_thread (0);
+    }
+#endif
+
+  exit (result);
 }





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]