diff --git a/valgrind-3.12.0-quick-fatal-sigs.patch b/valgrind-3.12.0-quick-fatal-sigs.patch new file mode 100644 index 0000000..c9133fc --- /dev/null +++ b/valgrind-3.12.0-quick-fatal-sigs.patch @@ -0,0 +1,103 @@ +commit eee2c95b91b2fdcb36c0b1a2ab15df4a44ee2986 +Author: philippe +Date: Sat Nov 19 13:51:41 2016 +0000 + + Fix Bug 372600 - process loops forever when fatal signals are arriving quickly + + + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16140 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c +index 168b681..b398882 100644 +--- a/coregrind/m_signals.c ++++ b/coregrind/m_signals.c +@@ -2430,8 +2430,14 @@ void async_signalhandler ( Int sigNo, + info->si_code = sanitize_si_code(info->si_code); + + if (VG_(clo_trace_signals)) +- VG_(dmsg)("async signal handler: signal=%d, tid=%u, si_code=%d\n", +- sigNo, tid, info->si_code); ++ VG_(dmsg)("async signal handler: signal=%d, tid=%u, si_code=%d, " ++ "exitreason %s\n", ++ sigNo, tid, info->si_code, ++ VG_(name_of_VgSchedReturnCode)(tst->exitreason)); ++ ++ /* */ ++ if (tst->exitreason == VgSrc_FatalSig) ++ resume_scheduler(tid); + + /* Update thread state properly. The signal can only have been + delivered whilst we were in +@@ -2479,8 +2485,16 @@ void async_signalhandler ( Int sigNo, + ); + + /* (2) */ +- /* Set up the thread's state to deliver a signal */ +- if (!is_sig_ign(info, tid)) ++ /* Set up the thread's state to deliver a signal. ++ However, if exitreason is VgSrc_FatalSig, then thread tid was ++ taken out of a syscall by VG_(nuke_all_threads_except). ++ But after the emission of VKI_SIGKILL, another (fatal) async ++ signal might be sent. In such a case, we must not handle this ++ signal, as the thread is supposed to die first. ++ => resume the scheduler for such a thread, so that the scheduler ++ can let the thread die. */ ++ if (tst->exitreason != VgSrc_FatalSig ++ && !is_sig_ign(info, tid)) + deliver_signal(tid, info, uc); + + /* It's crucial that (1) and (2) happen in the order (1) then (2) +@@ -2946,6 +2960,20 @@ void VG_(poll_signals)(ThreadId tid) + ThreadState *tst = VG_(get_ThreadState)(tid); + vki_sigset_t saved_mask; + ++ if (tst->exitreason == VgSrc_FatalSig) { ++ /* This task has been requested to die due to a fatal signal ++ received by the process. So, we cannot poll new signals, ++ as we are supposed to die asap. If we would poll and deliver ++ a new (maybe fatal) signal, this could cause a deadlock, as ++ this thread would believe it has to terminate the other threads ++ and wait for them to die, while we already have a thread doing ++ that. */ ++ if (VG_(clo_trace_signals)) ++ VG_(dmsg)("poll_signals: not polling as thread %u is exitreason %s\n", ++ tid, VG_(name_of_VgSchedReturnCode)(tst->exitreason)); ++ return; ++ } ++ + /* look for all the signals this thread isn't blocking */ + /* pollset = ~tst->sig_mask */ + VG_(sigcomplementset)( &pollset, &tst->sig_mask ); +@@ -2961,15 +2989,18 @@ void VG_(poll_signals)(ThreadId tid) + /* If there was nothing queued, ask the kernel for a pending signal */ + if (sip == NULL && VG_(sigtimedwait_zero)(&pollset, &si) > 0) { + if (VG_(clo_trace_signals)) +- VG_(dmsg)("poll_signals: got signal %d for thread %u\n", +- si.si_signo, tid); ++ VG_(dmsg)("poll_signals: got signal %d for thread %u exitreason %s\n", ++ si.si_signo, tid, ++ VG_(name_of_VgSchedReturnCode)(tst->exitreason)); + sip = &si; + } + + if (sip != NULL) { + /* OK, something to do; deliver it */ + if (VG_(clo_trace_signals)) +- VG_(dmsg)("Polling found signal %d for tid %u\n", sip->si_signo, tid); ++ VG_(dmsg)("Polling found signal %d for tid %u exitreason %s\n", ++ sip->si_signo, tid, ++ VG_(name_of_VgSchedReturnCode)(tst->exitreason)); + if (!is_sig_ign(sip, tid)) + deliver_signal(tid, sip, NULL); + else if (VG_(clo_trace_signals)) +@@ -3073,7 +3104,8 @@ void VG_(sigstartup_actions) ( void ) + } + + if (VG_(clo_trace_signals)) +- VG_(dmsg)("Max kernel-supported signal is %d\n", VG_(max_signal)); ++ VG_(dmsg)("Max kernel-supported signal is %d, VG_SIGVGKILL is %d\n", ++ VG_(max_signal), VG_SIGVGKILL); + + /* Our private internal signals are treated as ignored */ + scss.scss_per_sig[VG_SIGVGKILL].scss_handler = VKI_SIG_IGN; diff --git a/valgrind.spec b/valgrind.spec index 0ebb1c5..ba61c89 100644 --- a/valgrind.spec +++ b/valgrind.spec @@ -92,6 +92,9 @@ Patch8: valgrind-3.12.0-arm64-hint.patch # KDE#373192 Calling posix_spawn in glibc 2.24 completely broken Patch9: valgrind-3.12.0-clone-spawn.patch +# KDE#372600 process loops forever when fatal signals are arriving quickly +Patch10: valgrind-3.12.0-quick-fatal-sigs.patch + %if %{build_multilib} # Ensure glibc{,-devel} is installed for both multilib arches BuildRequires: /lib/libc.so.6 /usr/lib/libc.so /lib64/libc.so.6 /usr/lib64/libc.so @@ -210,6 +213,7 @@ Valgrind User Manual for details. %patch7 -p1 %patch8 -p1 %patch9 -p1 +%patch10 -p1 %build # We need to use the software collection compiler and binutils if available. @@ -407,6 +411,7 @@ echo ===============END TESTING=============== - Add valgrind-3.12.0-arm64-ppc64-prlimit64.patch - Add valgrind-3.12.0-arm64-hint.patch - Add valgrind-3.12.0-clone-spawn.patch +- Add valgrind-3.12.0-quick-fatal-sigs.patch * Fri Feb 17 2017 Mark Wielaard - 3.12.0-5 - Add valgrind-3.12.0-ppc64-r2.patch (#1424367)