|
From: Jeremy F. <je...@go...> - 2005-02-28 01:07:54
|
CVS commit by fitzhardinge:
Fix the sigsuspend syscalls, by making sure the change of the signal
mask is atomic with respect to the syscall blocking. This should fix
the problems with LinuxThreads programs hanging.
M +14 -16 vg_signals.c 1.133
M +1 -5 vg_syscalls.c 1.255
--- valgrind/coregrind/vg_syscalls.c #1.254:1.255
@@ -5461,5 +5461,4 @@ 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);
}
@@ -5475,8 +5474,6 @@ PRE(sys_rt_sigsuspend, MayBlock)
PRINT("sys_rt_sigsuspend ( %p, %d )", arg1,arg2 );
PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
- if (arg1 != (Addr)NULL) {
+ if (arg1 != (Addr)NULL)
SYS_PRE_MEM_READ( "rt_sigsuspend(mask)", arg1, sizeof(vki_sigset_t) );
- tst->eff_sig_mask = *(vki_sigset_t *)arg1;
- }
}
--- valgrind/coregrind/vg_signals.c #1.132:1.133
@@ -1621,4 +1621,10 @@ void vg_async_signalhandler ( Int sigNo,
sigNo, tid, info->si_code);
+ /* Update the thread's effective signal mask. The only syscall
+ this should apply to is sigsuspend, which has a temporary signal
+ mask set for signals delivered while it is blocked. The signal
+ handler will restore this on signal return. */
+ tst->eff_sig_mask = uc->uc_sigmask;
+
/* Update thread state properly */
VGA_(interrupted_syscall)(tid, uc,
@@ -1729,17 +1735,11 @@ void vg_sync_signalhandler ( Int sigNo,
Action: make thread runnable, queue signal, resume scheduler
*/
- Bool resume_sched = False;
-
if (VG_(threads)[tid].status == VgTs_WaitSys) {
- /* This is like a normal async signal, but we can't simply
- call async_signalhandler because the client may actually
- have the signal blocked, so we still need to queue it. */
- resume_sched = True;
-
- VG_(set_running)(tid);
-
- /* Update thread state properly */
- VGA_(interrupted_syscall)(tid, uc,
- !!(vg_scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART));
+ /* Since this signal interrupted a syscall, it means the
+ client's signal mask was applied, so we can't get here
+ unless the client wants this signal right now. This means
+ we can simply use the async_signalhandler. */
+ vg_async_signalhandler(sigNo, info, uc);
+ VG_(core_panic)("vg_async_signalhandler returned!?\n");
}
@@ -1769,6 +1769,6 @@ 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);
+ VG_(message)(Vg_DebugMsg, "Routing user-sent sync signal %d via queue",
+ sigNo);
/* Since every thread has these signals unblocked, we can't rely
@@ -1780,6 +1780,4 @@ void vg_sync_signalhandler ( Int sigNo,
queue_signal(0, info); /* shared pending */
- if (resume_sched)
- VG_(resume_scheduler)(tid);
return;
}
|