From 130e572a103afff0487a91bcd8630b21ab12da5e Mon Sep 17 00:00:00 2001 From: kamil Date: Sun, 13 Oct 2019 03:19:57 +0000 Subject: [PATCH] Fix one the the root causes of unreliability of the ptrace(2)ed threads In case of sigswitchin away in issignal() and continuing the execution on PT_CONTINUE (or equivalent call), there is a time window when another thread could cause the process state to be changed to PS_STOPPING. In the current logic, a thread would receive signal 0 (no-signal) and exit from issignal(), returning to userland and never finishing the process of stopping all LWPs. This causes hangs waitpid() waiting for SIGCHLD and the callout polling for the state of the process in an infinite loop. Instead of prompting for a returned signal from a debugger, repeat the issignal() loop, this will cause checking the PS_STOPPING flag again and sigswitching away in the scenario of stopping the process. --- sys/kern/kern_sig.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 39ebea3d6196..5fea55603bbe 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_sig.c,v 1.370 2019/10/13 03:10:22 kamil Exp $ */ +/* $NetBSD: kern_sig.c,v 1.371 2019/10/13 03:19:57 kamil Exp $ */ /*- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -70,7 +70,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.370 2019/10/13 03:10:22 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.371 2019/10/13 03:19:57 kamil Exp $"); #include "opt_ptrace.h" #include "opt_dtrace.h" @@ -1865,7 +1865,7 @@ issignal(struct lwp *l) if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0) { sigswitch_unlock_and_switch_away(l); mutex_enter(p->p_lock); - signo = sigchecktrace(); + continue; } else if (p->p_stat == SACTIVE) signo = sigchecktrace(); else