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