|
From: Jeremy F. <je...@go...> - 2005-01-28 09:08:20
|
CVS commit by fitzhardinge:
Honour SIG_IGN. Previously Valgrind was delivering ignored signals as
SIG_DFL. Surprising this doesn't break more stuff...
M +33 -27 vg_signals.c 1.115
--- valgrind/coregrind/vg_signals.c #1.114:1.115
@@ -352,5 +352,5 @@ static void handle_SCSS_change ( Bool fo
VG_(sigdelset)( &ksa.sa_mask, VKI_SIGSTOP );
- if (VG_(clo_trace_signals))
+ if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
VG_(message)(Vg_DebugMsg,
"setting ksig %d to: hdlr 0x%x, flags 0x%x, "
@@ -1217,6 +1217,6 @@ static void vg_default_action(const vki_
if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "delivering %d (code %d) to default handler %s%s",
- sigNo, info->si_code, terminate ? "terminate" : "", core ? "+core" : "");
+ VG_(message)(Vg_DebugMsg, "delivering %d (code %d) to default handler; action: %s%s",
+ sigNo, info->si_code, terminate ? "terminate" : "ignore", core ? "+core" : "");
if (!terminate)
@@ -1379,8 +1379,4 @@ void VG_(synth_fault)(ThreadId tid)
cause the thread to enter the signal handler.
- Note that this doesn't check the signal mask either. The
- assumption is that whoever calls this has already determined that
- the thread must get the signal.
-
This updates the thread state, but it does not set it to be
Runnable.
@@ -1490,5 +1486,9 @@ void queue_signal(ThreadId tid, const vk
/* Add signal to the queue. If the queue gets overrun, then old
- queued signals may get lost. */
+ queued signals may get lost.
+
+ XXX We should also keep a sigset of pending signals, so that at
+ least a non-siginfo signal gets deliviered.
+ */
if (sq->sigs[sq->next].si_signo != 0)
VG_(message)(Vg_UserMsg, "Signal %d being dropped from thread %d's queue\n",
@@ -1566,9 +1566,9 @@ void vg_async_signalhandler ( Int sigNo,
/* Set up the thread's state to deliver a signal */
+ if (!VG_(is_sig_ign)(info->si_signo))
VG_(deliver_signal)(tid, info);
/* longjmp back to the thread's main loop to start executing the
- handler.
- */
+ handler. */
VG_(resume_scheduler)(tid);
@@ -1876,29 +1876,35 @@ void VG_(poll_signals)(ThreadId tid)
pollset.sig[i] = ~tst->sig_mask.sig[i];
- VG_(sigdelset)(&pollset, VKI_SIGVGCHLD); /* never look for this */
+ VG_(sigdelset)(&pollset, VKI_SIGVGCHLD); /* already dealt with */
//VG_(printf)("tid %d pollset=%08x%08x\n", tid, pollset.sig[1], pollset.sig[0]);
- VG_(block_all_host_signals)(&saved_mask);
+ VG_(block_all_host_signals)(&saved_mask); // protect signal queue
/* First look for any queued pending signals */
- sip = next_queued(0, &pollset); /* process-wide */
- if (sip == NULL)
sip = next_queued(tid, &pollset); /* this thread */
- if (sip != NULL) {
- VG_(deliver_signal)(tid, sip);
- sip->si_signo = 0;
- VG_(restore_all_host_signals)(&saved_mask);
- return;
- }
- VG_(restore_all_host_signals)(&saved_mask);
- /* Grab a single pending signal for this thread, and deliver it to
- the thread */
- if (VG_(sigtimedwait)(&pollset, &si, &zero) > 0) {
+ if (sip == NULL)
+ sip = next_queued(0, &pollset); /* process-wide */
+
+ /* If there was nothing queued, ask the kernel for a pending signal */
+ if (sip == NULL && VG_(sigtimedwait)(&pollset, &si, &zero) > 0) {
if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugMsg, "poll_signals: got signal %d for thread %d", si.si_signo, tid);
- VG_(deliver_signal)(tid, &si);
+ sip = &si;
}
+
+ if (sip != NULL) {
+ /* OK, something to do; deliver it */
+ if (!VG_(is_sig_ign)(sip->si_signo))
+ VG_(deliver_signal)(tid, sip);
+ else if (VG_(clo_trace_signals))
+ VG_(message)(Vg_DebugMsg, " signal %d ignored", sip->si_signo);
+
+ sip->si_signo = 0; /* remove from signal queue, if that's
+ where it came from */
+ }
+
+ VG_(restore_all_host_signals)(&saved_mask);
}
@@ -1956,5 +1962,5 @@ void VG_(sigstartup_actions) ( void )
VG_(max_signal) = i;
- if (VG_(clo_trace_signals))
+ if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
VG_(printf)("snaffling handler 0x%x for signal %d\n",
(Addr)(sa.ksa_handler), i );
|