When creating new threads, initially block all signals. It's up to the
client code (in vg_libpthread.c) to set the appropriate signal mask when
its ready. This prevents a bug where a thread gets sent a signal before
even running any of its initialization code, which can cause problems
(particularly if the signal handler directly or indirectly uses TLS).
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2332 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_libpthread.c b/coregrind/vg_libpthread.c
index c5d7cb0..b64c543 100644
--- a/coregrind/vg_libpthread.c
+++ b/coregrind/vg_libpthread.c
@@ -71,6 +71,7 @@
#include <sys/poll.h>
#include <stdio.h>
#include <errno.h>
+#include <signal.h>
#include <stdlib.h>
@@ -752,6 +753,7 @@
unsigned long sysinfo;
void* (*root_fn) ( void* );
void* arg;
+ sigset_t sigmask;
}
NewThreadInfo;
@@ -817,9 +819,6 @@
set_gs(ldt_info.entry_number * 8 + 3);
}
- /* Free up the arg block that pthread_create malloced. */
- my_free(info);
-
/* Minimally observe the attributes supplied. */
if (attr__detachstate != PTHREAD_CREATE_DETACHED
&& attr__detachstate != PTHREAD_CREATE_JOINABLE)
@@ -830,6 +829,13 @@
/* Initialise thread specific state */
init_thread_specific_state();
+ /* Now that everything is set up, restore our signal mask (we're
+ ready to accept signals) */
+ sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
+
+ /* Free up the arg block that pthread_create malloced. */
+ my_free(info);
+
/* The root function might not return. But if it does we simply
move along to thread_exit_wrapper. All other ways out for the
thread (cancellation, or calling pthread_exit) lead there
@@ -922,6 +928,8 @@
info->root_fn = __start_routine;
info->arg = __arg;
+ sigprocmask(SIG_SETMASK, NULL, &info->sigmask);
+
VALGRIND_MAGIC_SEQUENCE(tid_child, VG_INVALID_THREADID /* default */,
VG_USERREQ__APPLY_IN_NEW_THREAD,
&thread_wrapper, info, 0, 0);
@@ -929,6 +937,7 @@
if (__thredd)
*__thredd = tid_child;
+
return 0; /* success */
}
diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c
index 0ec739c..9fc4ec1 100644
--- a/coregrind/vg_scheduler.c
+++ b/coregrind/vg_scheduler.c
@@ -1918,8 +1918,9 @@
print_sched_event(tid, msg_buf);
}
- /* We inherit our parent's signal mask. */
- VG_(threads)[tid].sig_mask = VG_(threads)[parent_tid].sig_mask;
+ /* Start the thread with all signals blocked; it's up to the client
+ code to set the right signal mask when it's ready. */
+ VG_(ksigfillset)(&VG_(threads)[tid].sig_mask);
/* Now that the signal mask is set up, create a proxy LWP for this thread */
VG_(proxy_create)(tid);