Let ptracestop() suspend threads sleeping in an SBDRY section.

When a thread enters ptracestop(), for example because it had received
SIGSTOP from ptrace(PT_ATTACH), it attempts to suspend other threads in
the same process. In the case of a thread sleeping interruptibly in an
SBDRY section, sig_suspend_threads() must wake the thread and allow it to
reach the user-mode boundary. However, sig_suspend_threads() would
erroneously avoid waking up such threads, resulting in an apparent hang.

Reviewed by:	kib
Tested by:	pho
MFC after:	2 weeks
Sponsored by:	Dell EMC Isilon
This commit is contained in:
markj 2017-05-11 17:03:45 +00:00
parent f5b2455b1a
commit 8ff278d791

View File

@ -2477,6 +2477,7 @@ sig_suspend_threads(struct thread *td, struct proc *p, int sending)
PROC_LOCK_ASSERT(p, MA_OWNED);
PROC_SLOCK_ASSERT(p, MA_OWNED);
MPASS(sending || td == curthread);
wakeup_swapper = 0;
FOREACH_THREAD_IN_PROC(p, td2) {
@ -2493,10 +2494,9 @@ sig_suspend_threads(struct thread *td, struct proc *p, int sending)
*/
KASSERT(!TD_IS_SUSPENDED(td2),
("thread with deferred stops suspended"));
if (TD_SBDRY_INTR(td2) && sending) {
if (TD_SBDRY_INTR(td2))
wakeup_swapper |= sleepq_abort(td2,
TD_SBDRY_ERRNO(td2));
}
} else if (!TD_IS_SUSPENDED(td2)) {
thread_suspend_one(td2);
}