Re: tst-basic3 failing

Paul Mackerras <[email protected]>
Newsgroups gmane.comp.lib.phil
Message-ID <[email protected]>
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);
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.