Module Name: src Committed By: martin Date: Tue Oct 15 19:08:46 UTC 2019
Modified Files: src/sys/kern [netbsd-9]: kern_sig.c Log Message: Pull up following revision(s) (requested by kamil in ticket #324): sys/kern/kern_sig.c: revision 1.367 Enhance reliability of ptrace(2) in a debuggee with multiple LWPs Stop competing between threads which one emits event signal quicker and overwriting the signal from another thread. This fixes missed in action signals. NetBSD truss can now report reliably all TRAP_SCE/SCX/etc events without reports of missed ones. his was one of the reasons why debuggee with multiple threads misbehaved under a debugger. This change is v.2 of the previously reverted commit for the same fix. This version contains recovery path that stopps triggering event SIGTRAP for a detached debugger. To generate a diff of this commit: cvs rdiff -u -r1.364.2.2 -r1.364.2.3 src/sys/kern/kern_sig.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_sig.c diff -u src/sys/kern/kern_sig.c:1.364.2.2 src/sys/kern/kern_sig.c:1.364.2.3 --- src/sys/kern/kern_sig.c:1.364.2.2 Tue Oct 15 19:01:06 2019 +++ src/sys/kern/kern_sig.c Tue Oct 15 19:08:46 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_sig.c,v 1.364.2.2 2019/10/15 19:01:06 martin Exp $ */ +/* $NetBSD: kern_sig.c,v 1.364.2.3 2019/10/15 19:08:46 martin Exp $ */ /*- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -70,7 +70,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.364.2.2 2019/10/15 19:01:06 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.364.2.3 2019/10/15 19:08:46 martin Exp $"); #include "opt_ptrace.h" #include "opt_dtrace.h" @@ -913,6 +913,7 @@ trapsignal(struct lwp *l, ksiginfo_t *ks mutex_enter(proc_lock); mutex_enter(p->p_lock); +repeat: /* * If we are exiting, demise now. * @@ -926,6 +927,16 @@ trapsignal(struct lwp *l, ksiginfo_t *ks /* 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 @@ eventswitch(int code, int pe_report_even 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 @@ eventswitch(int code, int pe_report_even } /* + * 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 @@ eventswitch(int code, int pe_report_even 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 @@ proc_stoptrace(int trapno, int sysnum, c mutex_enter(p->p_lock); +repeat: /* * If we are exiting, demise now. * @@ -2469,6 +2503,25 @@ proc_stoptrace(int trapno, int sysnum, c 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;