Module Name:    src
Committed By:   kamil
Date:           Fri Jun 21 04:02:58 UTC 2019

Modified Files:
        src/sys/kern: kern_sig.c

Log Message:
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.

This was one of the reasons why debuggee with multiple threads misbehaved
under a debugger.


To generate a diff of this commit:
cvs rdiff -u -r1.362 -r1.363 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.362 src/sys/kern/kern_sig.c:1.363
--- src/sys/kern/kern_sig.c:1.362	Fri Jun 21 01:03:51 2019
+++ src/sys/kern/kern_sig.c	Fri Jun 21 04:02:57 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_sig.c,v 1.362 2019/06/21 01:03:51 kamil Exp $	*/
+/*	$NetBSD: kern_sig.c,v 1.363 2019/06/21 04:02:57 kamil 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.362 2019/06/21 01:03:51 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.363 2019/06/21 04:02:57 kamil 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;
@@ -1580,6 +1591,7 @@ eventswitch(int code)
 	KASSERT((code == TRAP_CHLD) || (code == TRAP_LWP) ||
 	        (code == TRAP_EXEC));
 
+repeat:
 	/*
 	 * If we are exiting, demise now.
 	 *
@@ -1603,6 +1615,16 @@ eventswitch(int code)
 		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_info._signo = signo;
@@ -2434,6 +2456,7 @@ proc_stoptrace(int trapno, int sysnum, c
 
 	mutex_enter(p->p_lock);
 
+repeat:
 	/*
 	 * If we are exiting, demise now.
 	 *
@@ -2455,6 +2478,15 @@ proc_stoptrace(int trapno, int sysnum, c
 		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;

Reply via email to