diff options
author | Paul Pluzhnikov <ppluzhnikov@google.com> | 2014-01-11 16:34:15 -0800 |
---|---|---|
committer | Paul Pluzhnikov <ppluzhnikov@google.com> | 2014-01-11 16:34:15 -0800 |
commit | 2112e176757483dd25a7cf38ead63a237bf5e52e (patch) | |
tree | 80f02dd662d0da8f1fe40e96a2965aeb9ac23cba /nptl/tst-tls7.c | |
parent | 5d43293bacbdc09e0e060cfd002d2fb34b3facd3 (diff) | |
download | glibc-2112e176757483dd25a7cf38ead63a237bf5e52e.tar glibc-2112e176757483dd25a7cf38ead63a237bf5e52e.tar.gz glibc-2112e176757483dd25a7cf38ead63a237bf5e52e.tar.bz2 glibc-2112e176757483dd25a7cf38ead63a237bf5e52e.zip |
Fix a race in tst-tls7, which caused crashes on ppc32.
Diffstat (limited to 'nptl/tst-tls7.c')
-rw-r--r-- | nptl/tst-tls7.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/nptl/tst-tls7.c b/nptl/tst-tls7.c index 3bb3f7db6b..583d5b4620 100644 --- a/nptl/tst-tls7.c +++ b/nptl/tst-tls7.c @@ -19,6 +19,8 @@ /* This test checks that TLS in a dlopened object works when first accessed from a signal handler. */ +#include <assert.h> +#include <atomic.h> #include <dlfcn.h> #include <pthread.h> #include <semaphore.h> @@ -39,6 +41,23 @@ spin (void *ignored) return NULL; } +static void (*tls7mod_action) (int, siginfo_t *, void *); + +static void +action (int signo, siginfo_t *info, void *ignored) +{ + sem_t *sem = info->si_value.sival_ptr; + + atomic_read_barrier (); + assert (tls7mod_action != NULL); + (*tls7mod_action) (signo, info, ignored); + + /* This sem_post may trigger dlclose, which will invalidate tls7mod_action. + It is important to do that only after tls7mod_action is no longer + active. */ + sem_post (sem); +} + int do_test (void) { @@ -63,12 +82,13 @@ do_test (void) exit (1); } - void (*action) (int, siginfo_t *, void *) = dlsym (h, "action"); - if (action == NULL) + tls7mod_action = dlsym (h, "action"); + if (tls7mod_action == NULL) { puts ("dlsym for action failed"); exit (1); } + atomic_write_barrier (); struct sigaction sa; sa.sa_sigaction = action; @@ -105,6 +125,9 @@ do_test (void) } } + /* Paranoia. */ + tls7mod_action = NULL; + if (dlclose (h)) { puts ("dlclose failed"); |