Fix a race in tst-tls7, which caused crashes on ppc32.

This commit is contained in:
Paul Pluzhnikov 2014-01-11 16:34:15 -08:00
parent 5d43293bac
commit 2112e17675
3 changed files with 31 additions and 5 deletions

View File

@ -1,3 +1,9 @@
2014-01-11 Paul Pluzhnikov <ppluzhnikov@google.com>
* tst-tls7.c (action): New function.
(do_test): Call it.
* tst-tls7mod.c (action): Move sem_post to caller.
2014-01-03 Andrew Hunter <ahh@google.com>
* nptl/Makefile (tst-tls7): New test.

View File

@ -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");

View File

@ -29,7 +29,6 @@ static __thread intptr_t tls_data = 0xdeadbeef;
void
action (int signo, siginfo_t *info, void *ignored)
{
sem_t *sem = info->si_value.sival_ptr;
if (tls_data != 0xdeadbeef)
{
write (STDOUT_FILENO, "wrong TLS value\n", 17);
@ -38,6 +37,4 @@ action (int signo, siginfo_t *info, void *ignored)
/* arbitrary choice, just write something unique-ish. */
tls_data = (intptr_t) info;
sem_post (sem);
}