Index: sys/kern/kern_sig.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_sig.c,v retrieving revision 1.366 diff -u -r1.366 kern_sig.c --- sys/kern/kern_sig.c 3 Oct 2019 22:48:44 -0000 1.366 +++ sys/kern/kern_sig.c 8 Oct 2019 17:38:28 -0000 @@ -913,6 +913,7 @@ mutex_enter(proc_lock); mutex_enter(p->p_lock); +repeat: /* * If we are exiting, demise now. * @@ -926,6 +927,16 @@ /* NOTREACHED */ } + /* + * The process is already stopping. + */ + if ((p->p_sflag & PS_STOPPING) != 0) { + sigswitch(0, p->p_xsig, false); + mutex_enter(proc_lock); + mutex_enter(p->p_lock); + goto repeat; /* XXX */ + } + mask = &l->l_sigmask; ps = p->p_sigacts; action = SIGACTION_PS(ps, signo).sa_handler; @@ -1589,11 +1600,12 @@ KASSERT((code == TRAP_CHLD) || (code == TRAP_LWP) || (code == TRAP_EXEC)); +repeat: /* * If we are exiting, demise now. * * This avoids notifying tracer and deadlocking. - */ + */ if (__predict_false(ISSET(p->p_sflag, PS_WEXIT))) { mutex_exit(p->p_lock); mutex_exit(proc_lock); @@ -1603,6 +1615,17 @@ } /* + * If we are no longer traced, abandon this event signal. + * + * This avoids killing a process after detaching the debugger. + */ + if (__predict_false(!ISSET(p->p_slflag, PSL_TRACED))) { + mutex_exit(p->p_lock); + mutex_exit(proc_lock); + return; + } + + /* * If there's a pending SIGKILL process it immediately. */ if (p->p_xsig == SIGKILL || @@ -1612,6 +1635,16 @@ return; } + /* + * The process is already stopping. + */ + if ((p->p_sflag & PS_STOPPING) != 0) { + sigswitch(0, p->p_xsig, false); + mutex_enter(proc_lock); + mutex_enter(p->p_lock); + goto repeat; /* XXX */ + } + KSI_INIT_TRAP(&ksi); ksi.ksi_lid = l->l_lid; ksi.ksi_signo = signo; @@ -2448,6 +2481,7 @@ mutex_enter(p->p_lock); +repeat: /* * If we are exiting, demise now. * @@ -2469,6 +2503,25 @@ return; } + /* + * If we are no longer traced, abandon this event signal. + * + * This avoids killing a process after detaching the debugger. + */ + if (__predict_false(!ISSET(p->p_slflag, PSL_TRACED))) { + mutex_exit(p->p_lock); + return; + } + + /* + * The process is already stopping. + */ + if ((p->p_sflag & PS_STOPPING) != 0) { + sigswitch(0, p->p_xsig, true); + mutex_enter(p->p_lock); + goto repeat; /* XXX */ + } + /* Needed for ktrace */ ps = p->p_sigacts; action = SIGACTION_PS(ps, signo).sa_handler; Index: sys/kern/sys_ptrace_common.c =================================================================== RCS file: /cvsroot/src/sys/kern/sys_ptrace_common.c,v retrieving revision 1.65 diff -u -r1.65 sys_ptrace_common.c --- sys/kern/sys_ptrace_common.c 8 Oct 2019 12:29:57 -0000 1.65 +++ sys/kern/sys_ptrace_common.c 8 Oct 2019 17:38:28 -0000 @@ -511,8 +511,13 @@ /* * (3) it's not currently stopped. + * + * As an exception PT_CONTINUE is allowed here and will + * behave like kill(2) for a running process. + * */ - if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) { + if (req != PT_CONTINUE && + (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */)) { DPRINTF(("stat %d flag %d\n", t->p_stat, !t->p_waited)); return EBUSY; @@ -1326,6 +1331,8 @@ CLR(lt2->l_pflag, LP_SINGLESTEP); } CLR(lt->l_pflag, LP_SINGLESTEP); + } else if (req == PT_CONTINUE && t->p_stat != SSTOP) { + t->p_sigctx.ps_faked = 0; } sendsig: error = ptrace_sendsig(t, lt, signo, resume_all);