This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


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

pthread_exit_process


Hi!

This change breaks process-wide exit from thread other than main.

2000-03-19  Ulrich Drepper  <drepper@redhat.com>

        * pthread.c (pthread_initialize): Instead of on_exit use
        __cxa_atexit if __dso_label is available to allow unloading the
        libpthread shared library.

Specifically,
  if (__builtin_expect (&__dso_handle != NULL, 1))
    /* The cast is a bit unclean.  The function expects two arguments but
       we can only pass one.  Fortunately this is not a problem since the
       second argument of `pthread_exit_process' is simply ignored.  */
    __cxa_atexit((void (*) (void *)) pthread_exit_process, NULL, __dso_handle);
  else
    __on_exit (pthread_exit_process, NULL);
if pthread_exit_process is registered with __cxa_atexit, it means it will be
passed retcode 0 (well, the 2nd argument to __cxa_atexit) and random thing
as second argument.
First I thought about passing status as hidden second argument to cxa_exit
and take it from there (and pass 0 during cxa_finalize), the problem is that
as __cxa_atexit is called very early, the callback won't be ever called from
exit() but always from __cxa_finalize (because atexit _dl_fini and _fini
were registered later).
The patch below contains a testcase plus fixes this if ld supports -z nodelete,
while if it does not, it will be still broken.
Alternatives IMHO include just bailing out if ld does not support -z
nodelete during configure, or some global __exitcode variable set at the
beginning of exit() which would pthread_exit_process read.

2001-01-11  Jakub Jelinek  <jakub@redhat.com>

	* Makefile (tests): Add ex15.
	(CFLAGS-pthread.c): Add -DHAVE_Z_NODELETE if ld supports -z nodelete.
	* pthread.c (pthread_initialize): Use __on_exit unconditionally if
	libpthread is linked with -z nodelete.
	* Examples/ex15.c: New test.

--- libc/linuxthreads/Examples/ex15.c.jj	Thu Jan 11 16:36:25 2001
+++ libc/linuxthreads/Examples/ex15.c	Thu Jan 11 16:40:37 2001
@@ -0,0 +1,56 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <pthread.h>
+#include <unistd.h>
+
+static void *
+worker (void *dummy)
+{
+  exit (26);
+}
+
+#define TEST_FUNCTION do_test ()
+#define TIMEOUT 10
+static int
+do_test (void)
+{
+  pthread_t th;
+  pid_t pid;
+  int status;
+
+  switch ((pid = fork ()))
+    {
+    case -1:
+      puts ("Could not fork");
+      exit (1);
+    case 0:
+      if (pthread_create(&th, NULL, worker, NULL) != 0)
+	{
+	  puts ("Failed to start thread");
+	  exit (1);
+	}
+      for (;;);
+      exit (1);
+    default:
+      break;
+    }
+
+  if (waitpid (pid, &status, 0) != pid)
+    {
+      puts ("waitpid failed");
+      exit (1);
+    }
+
+  if (!WIFEXITED (status) || WEXITSTATUS (status) != 26)
+    {
+      printf ("Wrong exit code %d\n", status);
+      exit (1);
+    }
+
+  puts ("All OK");
+  return 0;
+}
+
+#include "../test-skeleton.c"
--- libc/linuxthreads/Makefile.jj	Fri Sep  8 17:51:18 2000
+++ libc/linuxthreads/Makefile	Thu Jan 11 16:37:48 2001
@@ -46,7 +46,7 @@ include ../Makeconfig
 
 librt-tests = ex10 ex11
 tests = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 $(librt-tests) ex12 ex13 joinrace \
-	tststack $(tests-nodelete-$(have-z-nodelete)) ecmutex ex14
+	tststack $(tests-nodelete-$(have-z-nodelete)) ecmutex ex14 ex15
 
 ifeq (yes,$(build-shared))
 tests-nodelete-yes = unload
@@ -54,9 +54,10 @@ endif
 
 include ../Rules
 
+znodelete-yes = -DHAVE_Z_NODELETE
 CFLAGS-mutex.c += -D__NO_WEAK_PTHREAD_ALIASES
 CFLAGS-specific.c += -D__NO_WEAK_PTHREAD_ALIASES
-CFLAGS-pthread.c += -D__NO_WEAK_PTHREAD_ALIASES
+CFLAGS-pthread.c += -D__NO_WEAK_PTHREAD_ALIASES $(znodelete-$(have-z-nodelete))
 CFLAGS-ptfork.c += -D__NO_WEAK_PTHREAD_ALIASES
 CFLAGS-cancel.c += -D__NO_WEAK_PTHREAD_ALIASES
 CFLAGS-unload.c += -DPREFIX=\"$(objpfx)\"
--- libc/linuxthreads/pthread.c.jj	Wed Jan 10 15:29:21 2001
+++ libc/linuxthreads/pthread.c	Thu Jan 11 16:18:14 2001
@@ -434,12 +434,11 @@ static void pthread_initialize(void)
   /* Register an exit function to kill all other threads. */
   /* Do it early so that user-registered atexit functions are called
      before pthread_exit_process. */
+#ifndef HAVE_Z_NODELETE
   if (__builtin_expect (&__dso_handle != NULL, 1))
-    /* The cast is a bit unclean.  The function expects two arguments but
-       we can only pass one.  Fortunately this is not a problem since the
-       second argument of `pthread_exit_process' is simply ignored.  */
     __cxa_atexit((void (*) (void *)) pthread_exit_process, NULL, __dso_handle);
   else
+#endif
     __on_exit (pthread_exit_process, NULL);
   /* How many processors.  */
   __pthread_smp_kernel = is_smp_system ();


	Jakub

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