From: Jeremy Fitzhardinge Date: Tue, 16 Mar 2004 22:09:12 +0000 (+0000) Subject: When creating new threads, initially block all signals. It's up to the X-Git-Tag: svn/VALGRIND_2_1_2~173 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d402c5408ce6723995e2b1b05dd2298b08039152;p=thirdparty%2Fvalgrind.git 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 --- diff --git a/coregrind/vg_libpthread.c b/coregrind/vg_libpthread.c index c5d7cb0c3e..b64c543796 100644 --- a/coregrind/vg_libpthread.c +++ b/coregrind/vg_libpthread.c @@ -71,6 +71,7 @@ #include #include #include +#include #include @@ -752,6 +753,7 @@ typedef unsigned long sysinfo; void* (*root_fn) ( void* ); void* arg; + sigset_t sigmask; } NewThreadInfo; @@ -817,9 +819,6 @@ void thread_wrapper ( NewThreadInfo* info ) 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 @@ void thread_wrapper ( NewThreadInfo* info ) /* 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 @@ pthread_create (pthread_t *__restrict __thredd, 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 @@ pthread_create (pthread_t *__restrict __thredd, if (__thredd) *__thredd = tid_child; + return 0; /* success */ } diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c index 0ec739c4c3..9fc4ec12eb 100644 --- a/coregrind/vg_scheduler.c +++ b/coregrind/vg_scheduler.c @@ -1918,8 +1918,9 @@ void do__apply_in_new_thread ( ThreadId parent_tid, 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);