|
From: Jeremy F. <je...@go...> - 2005-02-21 09:09:18
|
CVS commit by fitzhardinge:
Fix sigsuspend. sigsuspend() sets a temporary signal mask, which is in
effect for any signal delivered while sigsuspend is blocked. This
patch re-adds the eff_sig_mask member of ThreadState, which is the effective
signal mask; sig_mask is the one which was set by the last call to
sigprocmask. Apart from sigsuspend, they're always set together, and
eff_sig_mask is the only one looked at to find the current signal mask.
M +7 -0 core.h 1.87
M +1 -0 vg_scheduler.c 1.223
M +15 -9 vg_signals.c 1.124
M +4 -2 vg_syscalls.c 1.251
M +3 -1 linux/core_os.c 1.8
M +2 -1 x86-linux/syscalls.c 1.24
--- valgrind/coregrind/vg_syscalls.c #1.250:1.251
@@ -1804,5 +1804,5 @@ PRE(sys_execve, Special)
;
- VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
+ VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->eff_sig_mask, NULL);
}
@@ -5432,4 +5432,5 @@ PRE(sys_sigsuspend, MayBlock)
int, history0, int, history1,
vki_old_sigset_t, mask);
+ convert_sigset_to_rt((vki_old_sigset_t *)arg3, &tst->eff_sig_mask);
}
@@ -5447,4 +5448,5 @@ PRE(sys_rt_sigsuspend, MayBlock)
if (arg1 != (Addr)NULL) {
SYS_PRE_MEM_READ( "rt_sigsuspend(mask)", arg1, sizeof(vki_sigset_t) );
+ tst->eff_sig_mask = *(vki_sigset_t *)arg1;
}
}
@@ -6068,5 +6070,5 @@ void VG_(client_syscall) ( ThreadId tid
PRINT(" --> ...\n");
- mask = tst->sig_mask;
+ mask = tst->eff_sig_mask;
VG_(sanitize_client_sigmask)(tid, &mask);
--- valgrind/coregrind/core.h #1.86:1.87
@@ -632,4 +632,11 @@ struct _ThreadState {
vki_sigset_t sig_mask;
+ /* Effective signal mask, eff_sig_mask, is usually identical to
+ sig_mask, except when running sigsuspend. sigsuspend sets a
+ temporary signal mask while it runs, which is retained while any
+ signal handler is run; sig_mask comes into effect once the
+ handler has finished. */
+ vki_sigset_t eff_sig_mask;
+
/* A little signal queue for signals we can't get the kernel to
queue for us. This is only allocated as needed, since it should
--- valgrind/coregrind/vg_signals.c #1.123:1.124
@@ -99,5 +99,5 @@ static const Char *signame(Int sigNo);
Int VG_(max_signal) = _VKI_NSIG;
-#define N_QUEUED_SIGNALS 4
+#define N_QUEUED_SIGNALS 8
typedef struct SigQueue {
@@ -662,5 +662,5 @@ void do_setmask ( ThreadId tid,
vg_assert(VG_(is_valid_tid)(tid));
if (oldset) {
- *oldset = VG_(threads)[tid].sig_mask;
+ *oldset = VG_(threads)[tid].eff_sig_mask;
if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugExtraMsg,
@@ -672,4 +672,5 @@ void do_setmask ( ThreadId tid,
VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGKILL);
VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGSTOP);
+ VG_(threads)[tid].eff_sig_mask = VG_(threads)[tid].sig_mask;
}
}
@@ -1398,5 +1399,5 @@ static void synth_fault_common(ThreadId
/* If they're trying to block the signal, force it to be delivered */
- if (VG_(sigismember)(&VG_(threads)[tid].sig_mask, VKI_SIGSEGV))
+ if (VG_(sigismember)(&VG_(threads)[tid].eff_sig_mask, VKI_SIGSEGV))
VG_(set_default_handler)(VKI_SIGSEGV);
@@ -1491,10 +1492,10 @@ void VG_(deliver_signal) ( ThreadId tid,
mask. The original sigmask has already been saved in the
signal frame, and will be restored on signal return. */
- VG_(sigaddset_from_set)(&tst->sig_mask, &handler->scss_mask);
- VG_(sigaddset_from_set)(&tst->sig_mask, &VG_(threads)[tid].sig_mask);
+ VG_(sigaddset_from_set)(&tst->eff_sig_mask, &handler->scss_mask);
+ VG_(sigaddset_from_set)(&tst->eff_sig_mask, &VG_(threads)[tid].sig_mask);
/* also mask this signal, unless they ask us not to */
if (!(handler->scss_flags & VKI_SA_NOMASK))
- VG_(sigaddset)(&tst->sig_mask, sigNo);
+ VG_(sigaddset)(&tst->eff_sig_mask, sigNo);
}
@@ -1537,5 +1538,5 @@ void queue_signal(ThreadId tid, const vk
*/
if (sq->sigs[sq->next].si_signo != 0)
- VG_(message)(Vg_UserMsg, "Signal %d being dropped from thread %d's queue\n",
+ VG_(message)(Vg_UserMsg, "Signal %d being dropped from thread %d's queue",
sq->sigs[sq->next].si_signo, tid);
@@ -1718,4 +1719,8 @@ void vg_sync_signalhandler ( Int sigNo,
}
+ if (VG_(clo_trace_signals))
+ VG_(message)(Vg_DebugMsg, "Routing user-sent sync signal %d via queue; resume_sched=%d",
+ sigNo, resume_sched);
+
/* Since every thread has these signals unblocked, we can't rely
on the kernel to route them properly, so we need to queue
@@ -1807,5 +1812,5 @@ void vg_sync_signalhandler ( Int sigNo,
ThreadState *tst = VG_(get_ThreadState)(VG_(get_lwp_tid)(VG_(gettid)()));
- if (VG_(sigismember)(&tst->sig_mask, sigNo)) {
+ if (VG_(sigismember)(&tst->eff_sig_mask, sigNo)) {
/* signal is blocked, but they're not allowed to block faults */
VG_(set_default_handler)(sigNo);
@@ -1925,5 +1930,5 @@ void VG_(poll_signals)(ThreadId tid)
/* look for all the signals this thread isn't blocking */
for(i = 0; i < _VKI_NSIG_WORDS; i++)
- pollset.sig[i] = ~tst->sig_mask.sig[i];
+ pollset.sig[i] = ~tst->eff_sig_mask.sig[i];
VG_(sigdelset)(&pollset, VKI_SIGVGCHLD); /* already dealt with */
@@ -2059,4 +2064,5 @@ void VG_(sigstartup_actions) ( void )
vg_assert(VG_(threads)[VG_(master_tid)].status == VgTs_Init);
VG_(threads)[VG_(master_tid)].sig_mask = saved_procmask;
+ VG_(threads)[VG_(master_tid)].eff_sig_mask = saved_procmask;
/* Calculate SKSS and apply it. This also sets the initial kernel
--- valgrind/coregrind/vg_scheduler.c #1.222:1.223
@@ -501,4 +501,5 @@ void mostly_clear_thread_record ( Thread
VG_(sigemptyset)(&VG_(threads)[tid].sig_mask);
+ VG_(sigemptyset)(&VG_(threads)[tid].eff_sig_mask);
VGA_(os_state_init)(&VG_(threads)[tid]);
--- valgrind/coregrind/x86-linux/syscalls.c #1.23:1.24
@@ -327,5 +327,6 @@ static Int do_clone(ThreadId ptid,
/* inherit signal mask */
- ctst->sig_mask = ptst->sig_mask;
+ ctst->sig_mask = ptst->eff_sig_mask;
+ ctst->eff_sig_mask = ctst->sig_mask;
/* We don't really know where the client stack is, because its
--- valgrind/coregrind/linux/core_os.c #1.7:1.8
@@ -122,6 +122,8 @@ void VGA_(final_tidyup)(ThreadId tid)
// XXX should we use a special stack?
- /* block all blockable signals... */
+ /* Block all blockable signals by copying the real block state into
+ the thread's block state*/
VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
+ VG_(threads)[tid].eff_sig_mask = VG_(threads)[tid].sig_mask;
/* and restore handlers to default */
|