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