Module Name:    src
Committed By:   kamil
Date:           Fri May  3 22:34:21 UTC 2019

Modified Files:
        src/sys/kern: kern_exec.c kern_fork.c kern_lwp.c kern_sig.c sys_lwp.c
        src/sys/sys: signalvar.h

Log Message:
Register KTR events for debugger related signals

Register signals for:

 - crashes (FPE, SEGV, FPE, ILL, BUS)
 - LWP events
 - CHLD (FORK/VFORK/VFORK_DONE) events -- temporarily disabled
 - EXEC events

While there refactor related functions in order to simplify the code.

Add missing comment documentation for recently added kernel functions.


To generate a diff of this commit:
cvs rdiff -u -r1.463 -r1.464 src/sys/kern/kern_exec.c
cvs rdiff -u -r1.211 -r1.212 src/sys/kern/kern_fork.c
cvs rdiff -u -r1.199 -r1.200 src/sys/kern/kern_lwp.c
cvs rdiff -u -r1.356 -r1.357 src/sys/kern/kern_sig.c
cvs rdiff -u -r1.66 -r1.67 src/sys/kern/sys_lwp.c
cvs rdiff -u -r1.92 -r1.93 src/sys/sys/signalvar.h

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_exec.c
diff -u src/sys/kern/kern_exec.c:1.463 src/sys/kern/kern_exec.c:1.464
--- src/sys/kern/kern_exec.c:1.463	Wed May  1 17:21:55 2019
+++ src/sys/kern/kern_exec.c	Fri May  3 22:34:21 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_exec.c,v 1.463 2019/05/01 17:21:55 kamil Exp $	*/
+/*	$NetBSD: kern_exec.c,v 1.464 2019/05/03 22:34:21 kamil Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.463 2019/05/01 17:21:55 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.464 2019/05/03 22:34:21 kamil Exp $");
 
 #include "opt_exec.h"
 #include "opt_execfmt.h"
@@ -1271,9 +1271,7 @@ execve_runproc(struct lwp *l, struct exe
 
 	if ((p->p_slflag & (PSL_TRACED|PSL_SYSCALL)) == PSL_TRACED) {
 		mutex_enter(p->p_lock);
-		eventswitch(SIGTRAP, TRAP_EXEC);
-		// XXX ktrpoint(KTR_PSIG)
-		mutex_exit(p->p_lock);
+		eventswitch(TRAP_EXEC);
 		mutex_enter(proc_lock);
 	}
 

Index: src/sys/kern/kern_fork.c
diff -u src/sys/kern/kern_fork.c:1.211 src/sys/kern/kern_fork.c:1.212
--- src/sys/kern/kern_fork.c:1.211	Wed May  1 18:01:54 2019
+++ src/sys/kern/kern_fork.c	Fri May  3 22:34:21 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_fork.c,v 1.211 2019/05/01 18:01:54 kamil Exp $	*/
+/*	$NetBSD: kern_fork.c,v 1.212 2019/05/03 22:34:21 kamil Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2001, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.211 2019/05/01 18:01:54 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.212 2019/05/03 22:34:21 kamil Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_dtrace.h"
@@ -203,6 +203,9 @@ sys___clone(struct lwp *l, const struct 
  */
 static struct timeval fork_tfmrate = { 10, 0 };
 
+/*
+ * Check if a process is traced and shall inform about FORK events.
+ */
 static inline bool
 tracefork(struct proc *p, int flags)
 {
@@ -211,6 +214,9 @@ tracefork(struct proc *p, int flags)
 	    (PSL_TRACEFORK|PSL_TRACED) && (flags & FORK_PPWAIT) == 0;
 }
 
+/*
+ * Check if a process is traced and shall inform about VFORK events.
+ */
 static inline bool
 tracevfork(struct proc *p, int flags)
 {
@@ -219,6 +225,9 @@ tracevfork(struct proc *p, int flags)
 	    (PSL_TRACEVFORK|PSL_TRACED) && (flags & FORK_PPWAIT) != 0;
 }
 
+/*
+ * Check if a process is traced and shall inform about VFORK_DONE events.
+ */
 static inline bool
 tracevforkdone(struct proc *p, int flags)
 {
@@ -595,9 +604,7 @@ fork1(struct lwp *l1, int flags, int exi
 	 */
 	if (tracefork(p1, flags) || tracevfork(p1, flags)) {
 		mutex_enter(p1->p_lock);
-		eventswitch(SIGTRAP, TRAP_CHLD);
-		// XXX ktrpoint(KTR_PSIG)
-		mutex_exit(p1->p_lock);
+		eventswitch(TRAP_CHLD);
 		mutex_enter(proc_lock);
 	}
 
@@ -614,16 +621,16 @@ fork1(struct lwp *l1, int flags, int exi
 	if (tracevforkdone(p1, flags)) {
 		mutex_enter(p1->p_lock);
 		p1->p_vfpid_done = retval[0];
-		eventswitch(SIGTRAP, TRAP_CHLD);
-		// XXX ktrpoint(KTR_PSIG)
-		mutex_exit(p1->p_lock);
-		// proc_lock unlocked
+		eventswitch(TRAP_CHLD);
 	} else
 		mutex_exit(proc_lock);
 
 	return 0;
 }
 
+/*
+ * MI code executed in each newly spawned process before returning to userland.
+ */
 void
 child_return(void *arg)
 {
@@ -639,9 +646,7 @@ child_return(void *arg)
 		}
 
 		mutex_enter(p->p_lock);
-		eventswitch(SIGTRAP, TRAP_CHLD);
-		// XXX ktrpoint(KTR_PSIG)
-		mutex_exit(p->p_lock);
+		eventswitch(TRAP_CHLD);
 	}
 
 my_tracer_is_gone:

Index: src/sys/kern/kern_lwp.c
diff -u src/sys/kern/kern_lwp.c:1.199 src/sys/kern/kern_lwp.c:1.200
--- src/sys/kern/kern_lwp.c:1.199	Thu May  2 22:23:49 2019
+++ src/sys/kern/kern_lwp.c	Fri May  3 22:34:21 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_lwp.c,v 1.199 2019/05/02 22:23:49 kamil Exp $	*/
+/*	$NetBSD: kern_lwp.c,v 1.200 2019/05/03 22:34:21 kamil Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -211,7 +211,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.199 2019/05/02 22:23:49 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.200 2019/05/03 22:34:21 kamil Exp $");
 
 #include "opt_ddb.h"
 #include "opt_lockdebug.h"
@@ -1083,9 +1083,7 @@ lwp_exit(struct lwp *l)
 	    (PSL_TRACED|PSL_TRACELWP_EXIT)) {
 		mutex_enter(p->p_lock);
 		p->p_lwp_exited = l->l_lid;
-		eventswitch(SIGTRAP, TRAP_LWP);
-		// XXX ktrpoint(KTR_PSIG)
-		mutex_exit(p->p_lock);
+		eventswitch(TRAP_LWP);
 		mutex_enter(proc_lock);
 	}
 

Index: src/sys/kern/kern_sig.c
diff -u src/sys/kern/kern_sig.c:1.356 src/sys/kern/kern_sig.c:1.357
--- src/sys/kern/kern_sig.c:1.356	Thu May  2 22:23:49 2019
+++ src/sys/kern/kern_sig.c	Fri May  3 22:34:21 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_sig.c,v 1.356 2019/05/02 22:23:49 kamil Exp $	*/
+/*	$NetBSD: kern_sig.c,v 1.357 2019/05/03 22:34:21 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.356 2019/05/02 22:23:49 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.357 2019/05/03 22:34:21 kamil Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_dtrace.h"
@@ -902,6 +902,7 @@ trapsignal(struct lwp *l, ksiginfo_t *ks
 	struct sigacts	*ps;
 	int signo = ksi->ksi_signo;
 	sigset_t *mask;
+	sig_t action;
 
 	KASSERT(KSI_TRAP_P(ksi));
 
@@ -912,6 +913,10 @@ trapsignal(struct lwp *l, ksiginfo_t *ks
 	mutex_enter(proc_lock);
 	mutex_enter(p->p_lock);
 
+	mask = &l->l_sigmask;
+	ps = p->p_sigacts;
+	action = SIGACTION_PS(ps, signo).sa_handler;
+
 	if (ISSET(p->p_slflag, PSL_TRACED) &&
 	    !(p->p_pptr == p->p_opptr && ISSET(p->p_lflag, PL_PPWAIT)) &&
 	    p->p_xsig != SIGKILL &&
@@ -921,14 +926,16 @@ trapsignal(struct lwp *l, ksiginfo_t *ks
 		p->p_sigctx.ps_lwp = ksi->ksi_lid;
 		p->p_sigctx.ps_info = ksi->ksi_info;
 		sigswitch(0, signo, false);
-		// XXX ktrpoint(KTR_PSIG)
-		mutex_exit(p->p_lock);
+
+		if (ktrpoint(KTR_PSIG)) {
+			if (p->p_emul->e_ktrpsig)
+				p->p_emul->e_ktrpsig(signo, action, mask, ksi);
+			else
+				ktrpsig(signo, action, mask, ksi);
+		}
 		return;
 	}
 
-	mask = &l->l_sigmask;
-	ps = p->p_sigacts;
-
 	const bool caught = sigismember(&p->p_sigctx.ps_sigcatch, signo);
 	const bool masked = sigismember(mask, signo);
 	if (caught && !masked) {
@@ -936,15 +943,12 @@ trapsignal(struct lwp *l, ksiginfo_t *ks
 		l->l_ru.ru_nsignals++;
 		kpsendsig(l, ksi, mask);
 		mutex_exit(p->p_lock);
+
 		if (ktrpoint(KTR_PSIG)) {
 			if (p->p_emul->e_ktrpsig)
-				p->p_emul->e_ktrpsig(signo,
-				    SIGACTION_PS(ps, signo).sa_handler,
-				    mask, ksi);
+				p->p_emul->e_ktrpsig(signo, action, mask, ksi);
 			else
-				ktrpsig(signo, 
-				    SIGACTION_PS(ps, signo).sa_handler,
-				    mask, ksi);
+				ktrpsig(signo, action, mask, ksi);
 		}
 		return;
 	}
@@ -954,7 +958,7 @@ trapsignal(struct lwp *l, ksiginfo_t *ks
 	 * reset it to the default action so that the process or
 	 * its tracer will be notified.
 	 */
-	const bool ignored = SIGACTION_PS(ps, signo).sa_handler == SIG_IGN;
+	const bool ignored = action == SIG_IGN;
 	if (masked || ignored) {
 		mutex_enter(&ps->sa_mutex);
 		sigdelset(mask, signo);	
@@ -1539,35 +1543,68 @@ proc_stop_done(struct proc *p, int ppmas
 	}
 }
 
+/*
+ * Stop the current process and switch away to the debugger notifying
+ * an event specific to a traced process only.
+ */
 void
-eventswitch(int signo, int code)
+eventswitch(int code)
 {
 	struct lwp *l = curlwp;
 	struct proc *p = l->l_proc;
+	struct sigacts *ps;
+	sigset_t *mask;
+	sig_t action;
+	ksiginfo_t ksi;
+	const int signo = SIGTRAP;
 
 	KASSERT(mutex_owned(proc_lock));
 	KASSERT(mutex_owned(p->p_lock));
+	KASSERT(p->p_pptr != initproc);
 	KASSERT(l->l_stat == LSONPROC);
-	KASSERT((l->l_flag & LW_SYSTEM) == 0);
+	KASSERT(ISSET(p->p_slflag, PSL_TRACED));
+	KASSERT(!ISSET(l->l_flag, LW_SYSTEM));
 	KASSERT(p->p_nrlwps > 0);
+	KASSERT((code == TRAP_CHLD) || (code == TRAP_LWP) ||
+	        (code == TRAP_EXEC));
 
 	/*
 	 * If there's a pending SIGKILL process it immediately.
 	 */
 	if (p->p_xsig == SIGKILL ||
 	    sigismember(&p->p_sigpend.sp_set, SIGKILL)) {
+		mutex_exit(p->p_lock);
 		mutex_exit(proc_lock);
 		return;
 	}
 
+	KSI_INIT_TRAP(&ksi);
+	ksi.ksi_lid = l->l_lid;
+	ksi.ksi_info._signo = signo;
+	ksi.ksi_info._code = code;
+
+	/* Needed for ktrace */
+	ps = p->p_sigacts;
+	action = SIGACTION_PS(ps, signo).sa_handler;
+	mask = &l->l_sigmask;
+
 	p->p_xsig = signo;
 	p->p_sigctx.ps_faked = true;
-	p->p_sigctx.ps_lwp = l->l_lid;
-	memset(&p->p_sigctx.ps_info, 0, sizeof(p->p_sigctx.ps_info));
-	p->p_sigctx.ps_info._signo = signo;
-	p->p_sigctx.ps_info._code = code;
+	p->p_sigctx.ps_lwp = ksi.ksi_lid;
+	p->p_sigctx.ps_info = ksi.ksi_info;
 
 	sigswitch(0, signo, false);
+
+	/* XXX: hangs for VFORK */
+	if (code == TRAP_CHLD)
+		return;
+
+	if (ktrpoint(KTR_PSIG)) {
+		if (p->p_emul->e_ktrpsig)
+			p->p_emul->e_ktrpsig(signo, action, mask, &ksi);
+		else
+			ktrpsig(signo, action, mask, &ksi);
+	}
 }
 
 /*
@@ -1633,7 +1670,6 @@ sigswitch(int ppmask, int signo, bool re
 	lwp_lock(l);
 	mi_switch(l);
 	KERNEL_LOCK(biglocks, l);
-	mutex_enter(p->p_lock);
 }
 
 /*
@@ -1711,6 +1747,7 @@ issignal(struct lwp *l)
 		 */
 		if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0) {
 			sigswitch(PS_NOCLDSTOP, 0, true);
+			mutex_enter(p->p_lock);
 			signo = sigchecktrace();
 		} else if (p->p_stat == SACTIVE)
 			signo = sigchecktrace();
@@ -1782,6 +1819,7 @@ issignal(struct lwp *l)
 
 			/* Handling of signal trace */
 			sigswitch(0, signo, true);
+			mutex_enter(p->p_lock);
 
 			/* Check for a signal from the debugger. */
 			if ((signo = sigchecktrace()) == 0)
@@ -1838,6 +1876,7 @@ issignal(struct lwp *l)
 				p->p_sflag &= ~PS_CONTINUED;
 				signo = 0;
 				sigswitch(PS_NOCLDSTOP, p->p_xsig, true);
+				mutex_enter(p->p_lock);
 			} else if (prop & SA_IGNORE) {
 				/*
 				 * Except for SIGCONT, shouldn't get here.
@@ -2332,6 +2371,15 @@ proc_stoptrace(int trapno)
 
 	mutex_enter(p->p_lock);
 
+	/*
+	 * If there's a pending SIGKILL process it immediately.
+	 */
+	if (p->p_xsig == SIGKILL ||
+	    sigismember(&p->p_sigpend.sp_set, SIGKILL)) {
+		mutex_exit(p->p_lock);
+		return;
+	}
+
 	/* Needed for ktrace */
 	ps = p->p_sigacts;
 	action = SIGACTION_PS(ps, signo).sa_handler;
@@ -2347,7 +2395,6 @@ proc_stoptrace(int trapno)
 	p->p_sigctx.ps_lwp = ksi.ksi_lid;
 	p->p_sigctx.ps_info = ksi.ksi_info;
 	sigswitch(0, signo, true);
-	mutex_exit(p->p_lock);
 
 	if (ktrpoint(KTR_PSIG)) {
 		if (p->p_emul->e_ktrpsig)

Index: src/sys/kern/sys_lwp.c
diff -u src/sys/kern/sys_lwp.c:1.66 src/sys/kern/sys_lwp.c:1.67
--- src/sys/kern/sys_lwp.c:1.66	Thu May  2 22:23:49 2019
+++ src/sys/kern/sys_lwp.c	Fri May  3 22:34:21 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_lwp.c,v 1.66 2019/05/02 22:23:49 kamil Exp $	*/
+/*	$NetBSD: sys_lwp.c,v 1.67 2019/05/03 22:34:21 kamil Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.66 2019/05/02 22:23:49 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.67 2019/05/03 22:34:21 kamil Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -90,9 +90,7 @@ mi_startlwp(void *arg)
 
 		mutex_enter(p->p_lock);
 		p->p_lwp_created = l->l_lid;
-		eventswitch(SIGTRAP, TRAP_LWP);
-		// XXX ktrpoint(KTR_PSIG)
-		mutex_exit(p->p_lock);
+		eventswitch(TRAP_LWP);
 	}
 }
 

Index: src/sys/sys/signalvar.h
diff -u src/sys/sys/signalvar.h:1.92 src/sys/sys/signalvar.h:1.93
--- src/sys/sys/signalvar.h:1.92	Wed May  1 17:21:55 2019
+++ src/sys/sys/signalvar.h	Fri May  3 22:34:21 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: signalvar.h,v 1.92 2019/05/01 17:21:55 kamil Exp $	*/
+/*	$NetBSD: signalvar.h,v 1.93 2019/05/03 22:34:21 kamil Exp $	*/
 
 /*
  * Copyright (c) 1991, 1993
@@ -136,7 +136,7 @@ void	killproc(struct proc *, const char 
 void	setsigvec(struct proc *, int, struct sigaction *);
 int	killpg1(struct lwp *, struct ksiginfo *, int, int);
 void	proc_unstop(struct proc *p);
-void	eventswitch(int, int);
+void	eventswitch(int);
 void	sigswitch(int, int, bool);
 
 

Reply via email to