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);