work around "signal loses thread pointer" issue with "approach 2"

this was discussed on the mailing list and no consensus on the
preferred solution was reached, so in anticipation of a release, i'm
just committing a minimally-invasive solution that avoids the problem
by ensuring that multi-threaded-capable programs will always have
initialized the thread pointer before any signal handler can run.

in the long term we may switch to initializing the thread pointer at
program start time whenever the program has the potential to access
any per-thread data.
This commit is contained in:
Rich Felker 2012-02-27 18:51:02 -05:00
parent 834255a3ff
commit dac084a4c5
2 changed files with 8 additions and 2 deletions

View File

@ -3,9 +3,13 @@
#include <errno.h> #include <errno.h>
#include "syscall.h" #include "syscall.h"
#include "pthread_impl.h" #include "pthread_impl.h"
#include "libc.h"
void __restore(), __restore_rt(); void __restore(), __restore_rt();
static pthread_t dummy(void) { return 0; }
weak_alias(dummy, __pthread_self_def);
int __libc_sigaction(int sig, const struct sigaction *sa, struct sigaction *old) int __libc_sigaction(int sig, const struct sigaction *sa, struct sigaction *old)
{ {
struct { struct {
@ -23,6 +27,7 @@ int __libc_sigaction(int sig, const struct sigaction *sa, struct sigaction *old)
pksa = (long)&ksa; pksa = (long)&ksa;
} }
if (old) pkold = (long)&kold; if (old) pkold = (long)&kold;
__pthread_self_def();
if (syscall(SYS_rt_sigaction, sig, pksa, pkold, 8)) if (syscall(SYS_rt_sigaction, sig, pksa, pkold, 8))
return -1; return -1;
if (old) { if (old) {

View File

@ -19,7 +19,7 @@ static int init_main_thread()
return 0; return 0;
} }
pthread_t pthread_self() pthread_t __pthread_self_def()
{ {
static int init, failed; static int init, failed;
if (!init) { if (!init) {
@ -31,4 +31,5 @@ pthread_t pthread_self()
return __pthread_self(); return __pthread_self();
} }
weak_alias(pthread_self, __pthread_self_init); weak_alias(__pthread_self_def, pthread_self);
weak_alias(__pthread_self_def, __pthread_self_init);