|
From: Jeremy F. <je...@go...> - 2004-03-16 22:09:18
|
CVS commit by fitzhardinge:
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).
M +12 -3 vg_libpthread.c 1.148
M +3 -2 vg_scheduler.c 1.145
--- valgrind/coregrind/vg_libpthread.c #1.147:1.148
@@ -72,4 +72,5 @@
#include <stdio.h>
#include <errno.h>
+#include <signal.h>
#include <stdlib.h>
@@ -753,4 +754,5 @@ typedef
void* (*root_fn) ( void* );
void* arg;
+ sigset_t sigmask;
}
NewThreadInfo;
@@ -818,7 +820,4 @@ void thread_wrapper ( NewThreadInfo* inf
}
- /* Free up the arg block that pthread_create malloced. */
- my_free(info);
-
/* Minimally observe the attributes supplied. */
if (attr__detachstate != PTHREAD_CREATE_DETACHED
@@ -831,4 +830,11 @@ void thread_wrapper ( NewThreadInfo* inf
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
@@ -923,4 +929,6 @@ pthread_create (pthread_t *__restrict __
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,
--- valgrind/coregrind/vg_scheduler.c #1.144:1.145
@@ -1919,6 +1919,7 @@ void do__apply_in_new_thread ( ThreadId
}
- /* 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 */
|