Mark Wielaard fce22b
commit eee2c95b91b2fdcb36c0b1a2ab15df4a44ee2986
Mark Wielaard fce22b
Author: philippe <philippe@a5019735-40e9-0310-863c-91ae7b9d1cf9>
Mark Wielaard fce22b
Date:   Sat Nov 19 13:51:41 2016 +0000
Mark Wielaard fce22b
Mark Wielaard fce22b
    Fix Bug 372600 - process loops forever when fatal signals are arriving quickly
Mark Wielaard fce22b
    
Mark Wielaard fce22b
    
Mark Wielaard fce22b
    
Mark Wielaard fce22b
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16140 a5019735-40e9-0310-863c-91ae7b9d1cf9
Mark Wielaard fce22b
Mark Wielaard fce22b
diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c
Mark Wielaard fce22b
index 168b681..b398882 100644
Mark Wielaard fce22b
--- a/coregrind/m_signals.c
Mark Wielaard fce22b
+++ b/coregrind/m_signals.c
Mark Wielaard fce22b
@@ -2430,8 +2430,14 @@ void async_signalhandler ( Int sigNo,
Mark Wielaard fce22b
    info->si_code = sanitize_si_code(info->si_code);
Mark Wielaard fce22b
 
Mark Wielaard fce22b
    if (VG_(clo_trace_signals))
Mark Wielaard fce22b
-      VG_(dmsg)("async signal handler: signal=%d, tid=%u, si_code=%d\n",
Mark Wielaard fce22b
-                sigNo, tid, info->si_code);
Mark Wielaard fce22b
+      VG_(dmsg)("async signal handler: signal=%d, tid=%u, si_code=%d, "
Mark Wielaard fce22b
+                "exitreason %s\n",
Mark Wielaard fce22b
+                sigNo, tid, info->si_code,
Mark Wielaard fce22b
+                VG_(name_of_VgSchedReturnCode)(tst->exitreason));
Mark Wielaard fce22b
+
Mark Wielaard fce22b
+   /* */
Mark Wielaard fce22b
+   if (tst->exitreason == VgSrc_FatalSig)
Mark Wielaard fce22b
+      resume_scheduler(tid);
Mark Wielaard fce22b
 
Mark Wielaard fce22b
    /* Update thread state properly.  The signal can only have been
Mark Wielaard fce22b
       delivered whilst we were in
Mark Wielaard fce22b
@@ -2479,8 +2485,16 @@ void async_signalhandler ( Int sigNo,
Mark Wielaard fce22b
    );
Mark Wielaard fce22b
 
Mark Wielaard fce22b
    /* (2) */
Mark Wielaard fce22b
-   /* Set up the thread's state to deliver a signal */
Mark Wielaard fce22b
-   if (!is_sig_ign(info, tid))
Mark Wielaard fce22b
+   /* Set up the thread's state to deliver a signal.
Mark Wielaard fce22b
+      However, if exitreason is VgSrc_FatalSig, then thread tid was
Mark Wielaard fce22b
+      taken out of a syscall by VG_(nuke_all_threads_except).
Mark Wielaard fce22b
+      But after the emission of VKI_SIGKILL, another (fatal) async
Mark Wielaard fce22b
+      signal might be sent. In such a case, we must not handle this
Mark Wielaard fce22b
+      signal, as the thread is supposed to die first.
Mark Wielaard fce22b
+      => resume the scheduler for such a thread, so that the scheduler
Mark Wielaard fce22b
+      can let the thread die. */
Mark Wielaard fce22b
+   if (tst->exitreason != VgSrc_FatalSig 
Mark Wielaard fce22b
+       && !is_sig_ign(info, tid))
Mark Wielaard fce22b
       deliver_signal(tid, info, uc);
Mark Wielaard fce22b
 
Mark Wielaard fce22b
    /* It's crucial that (1) and (2) happen in the order (1) then (2)
Mark Wielaard fce22b
@@ -2946,6 +2960,20 @@ void VG_(poll_signals)(ThreadId tid)
Mark Wielaard fce22b
    ThreadState *tst = VG_(get_ThreadState)(tid);
Mark Wielaard fce22b
    vki_sigset_t saved_mask;
Mark Wielaard fce22b
 
Mark Wielaard fce22b
+   if (tst->exitreason == VgSrc_FatalSig) {
Mark Wielaard fce22b
+      /* This task has been requested to die due to a fatal signal
Mark Wielaard fce22b
+         received by the process. So, we cannot poll new signals,
Mark Wielaard fce22b
+         as we are supposed to die asap. If we would poll and deliver
Mark Wielaard fce22b
+         a new (maybe fatal) signal, this could cause a deadlock, as
Mark Wielaard fce22b
+         this thread would believe it has to terminate the other threads
Mark Wielaard fce22b
+         and wait for them to die, while we already have a thread doing
Mark Wielaard fce22b
+         that. */
Mark Wielaard fce22b
+      if (VG_(clo_trace_signals))
Mark Wielaard fce22b
+         VG_(dmsg)("poll_signals: not polling as thread %u is exitreason %s\n",
Mark Wielaard fce22b
+                   tid, VG_(name_of_VgSchedReturnCode)(tst->exitreason));
Mark Wielaard fce22b
+      return;
Mark Wielaard fce22b
+   }
Mark Wielaard fce22b
+
Mark Wielaard fce22b
    /* look for all the signals this thread isn't blocking */
Mark Wielaard fce22b
    /* pollset = ~tst->sig_mask */
Mark Wielaard fce22b
    VG_(sigcomplementset)( &pollset, &tst->sig_mask );
Mark Wielaard fce22b
@@ -2961,15 +2989,18 @@ void VG_(poll_signals)(ThreadId tid)
Mark Wielaard fce22b
    /* If there was nothing queued, ask the kernel for a pending signal */
Mark Wielaard fce22b
    if (sip == NULL && VG_(sigtimedwait_zero)(&pollset, &si) > 0) {
Mark Wielaard fce22b
       if (VG_(clo_trace_signals))
Mark Wielaard fce22b
-         VG_(dmsg)("poll_signals: got signal %d for thread %u\n",
Mark Wielaard fce22b
-                   si.si_signo, tid);
Mark Wielaard fce22b
+         VG_(dmsg)("poll_signals: got signal %d for thread %u exitreason %s\n",
Mark Wielaard fce22b
+                   si.si_signo, tid,
Mark Wielaard fce22b
+                   VG_(name_of_VgSchedReturnCode)(tst->exitreason));
Mark Wielaard fce22b
       sip = &si;
Mark Wielaard fce22b
    }
Mark Wielaard fce22b
 
Mark Wielaard fce22b
    if (sip != NULL) {
Mark Wielaard fce22b
       /* OK, something to do; deliver it */
Mark Wielaard fce22b
       if (VG_(clo_trace_signals))
Mark Wielaard fce22b
-         VG_(dmsg)("Polling found signal %d for tid %u\n", sip->si_signo, tid);
Mark Wielaard fce22b
+         VG_(dmsg)("Polling found signal %d for tid %u exitreason %s\n",
Mark Wielaard fce22b
+                   sip->si_signo, tid,
Mark Wielaard fce22b
+                   VG_(name_of_VgSchedReturnCode)(tst->exitreason));
Mark Wielaard fce22b
       if (!is_sig_ign(sip, tid))
Mark Wielaard fce22b
 	 deliver_signal(tid, sip, NULL);
Mark Wielaard fce22b
       else if (VG_(clo_trace_signals))
Mark Wielaard fce22b
@@ -3073,7 +3104,8 @@ void VG_(sigstartup_actions) ( void )
Mark Wielaard fce22b
    }
Mark Wielaard fce22b
 
Mark Wielaard fce22b
    if (VG_(clo_trace_signals))
Mark Wielaard fce22b
-      VG_(dmsg)("Max kernel-supported signal is %d\n", VG_(max_signal));
Mark Wielaard fce22b
+      VG_(dmsg)("Max kernel-supported signal is %d, VG_SIGVGKILL is %d\n",
Mark Wielaard fce22b
+                VG_(max_signal), VG_SIGVGKILL);
Mark Wielaard fce22b
 
Mark Wielaard fce22b
    /* Our private internal signals are treated as ignored */
Mark Wielaard fce22b
    scss.scss_per_sig[VG_SIGVGKILL].scss_handler = VKI_SIG_IGN;