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] |
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] |