]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
When creating new threads, initially block all signals. It's up to the
authorJeremy Fitzhardinge <jeremy@valgrind.org>
Tue, 16 Mar 2004 22:09:12 +0000 (22:09 +0000)
committerJeremy Fitzhardinge <jeremy@valgrind.org>
Tue, 16 Mar 2004 22:09:12 +0000 (22:09 +0000)
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

coregrind/vg_libpthread.c
coregrind/vg_scheduler.c

index c5d7cb0c3e5312862acbd8ed476d6c32a4748663..b64c54379601494e9ae6779842a7aa56269b1f47 100644 (file)
@@ -71,6 +71,7 @@
 #include <sys/poll.h>
 #include <stdio.h>
 #include <errno.h>
+#include <signal.h>
 
 #include <stdlib.h>
 
@@ -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 */
 }
 
index 0ec739c4c3de15dfcef4ef3bae8b3a49ff06167e..9fc4ec12eb6e28e80b889d83c7bd5dfc2785ded2 100644 (file)
@@ -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);