Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Improve the proc_stoptrace() function



details:   https://anonhg.NetBSD.org/src/rev/762fd6d0ec5c
branches:  trunk
changeset: 318616:762fd6d0ec5c
user:      kamil <kamil%NetBSD.org@localhost>
date:      Tue May 01 13:48:38 2018 +0000
description:
Improve the proc_stoptrace() function

proc_stoptrace() is dedicated for emitting a syscall trap for a debugger,
either on entry or exit of the system function routine.

Changes:
 - Change an if() branch of an invalid condition of being traced by
   initproc (PID1) to KASSERT(9).
 - Assert that the current process has set appropriate flags (PSL_TRACED
   and PSL_SYSCALL).
 - Use ktrpoint(KTR_PSIG) and ktrpsig()/e_ktrpsig() in order to register
   the emitted signal for the ktrace(1) event debugging.

Example of the new output from kdump(1) for the syscall debugger traps,
containing SIGTRAP notification with TRAP_SCE and TRAP_SCX (around
the getpid(2) call).

$ kdump /tmp/1.dat.qemu |grep 663
   588      1 t_ptrace_waitpid RET   fork 663/0x297
   663      1 t_ptrace_waitpid EMUL  "netbsd"
   663      1 t_ptrace_waitpid RET   fork 0
   663      1 t_ptrace_waitpid CALL  ptrace(PT_TRACE_ME,0,0,0)
   663      1 t_ptrace_waitpid RET   ptrace 0
   663      1 t_ptrace_waitpid CALL  _lwp_self
   663      1 t_ptrace_waitpid RET   _lwp_self 1
   663      1 t_ptrace_waitpid CALL  _lwp_kill(1,0x11)
   663      1 t_ptrace_waitpid RET   _lwp_kill 0
   588      1 t_ptrace_waitpid RET   __wait450 663/0x297
   663      1 t_ptrace_waitpid CALL  getpid
   588      1 t_ptrace_waitpid RET   __wait450 663/0x297
   663      1 t_ptrace_waitpid PSIG  SIGTRAP SIG_DFL: code=TRAP_SCE, addr=0x0, trap=0)
   663      1 t_ptrace_waitpid RET   getpid 663/0x297, 588/0x24c
   588      1 t_ptrace_waitpid RET   __wait450 663/0x297
   663      1 t_ptrace_waitpid PSIG  SIGTRAP SIG_DFL: code=TRAP_SCX, addr=0x0, trap=0)
   663      1 t_ptrace_waitpid CALL  exit(5)
   588      1 t_ptrace_waitpid RET   __wait450 663/0x297

Sponsored by <The NetBSD Foundation>

diffstat:

 sys/kern/kern_sig.c |  52 ++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 38 insertions(+), 14 deletions(-)

diffs (76 lines):

diff -r 03cee9df9a0f -r 762fd6d0ec5c sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c       Tue May 01 12:38:39 2018 +0000
+++ b/sys/kern/kern_sig.c       Tue May 01 13:48:38 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_sig.c,v 1.340 2018/04/24 18:34:46 kamil Exp $     */
+/*     $NetBSD: kern_sig.c,v 1.341 2018/05/01 13:48:38 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.340 2018/04/24 18:34:46 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.341 2018/05/01 13:48:38 kamil Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_dtrace.h"
@@ -2268,21 +2268,45 @@
 proc_stoptrace(int trapno)
 {
        struct lwp *l = curlwp;
-       struct proc *p = l->l_proc, *pp;
+       struct proc *p = l->l_proc;
+       struct sigacts *ps;
+       sigset_t *mask;
+       sig_t action;
+       ksiginfo_t ksi;
+       const int signo = SIGTRAP;
+
+       KASSERT((trapno == TRAP_SCE) || (trapno == TRAP_SCX));
+
+       KSI_INIT_TRAP(&ksi);
+       ksi.ksi_lid = l->l_lid;
+       ksi.ksi_info._signo = signo;
+       ksi.ksi_info._code = trapno;
 
        mutex_enter(p->p_lock);
-       pp = p->p_pptr;
-       if (pp->p_pid == 1) {
-               CLR(p->p_slflag, PSL_SYSCALL);  /* XXXSMP */
-               mutex_exit(p->p_lock);
-               return;
+
+       /* Needed for ktrace */
+       ps = p->p_sigacts;
+       action = SIGACTION_PS(ps, signo).sa_handler;
+       mask = &l->l_sigmask;
+
+       /* initproc (PID1) cannot became a debugger */
+       KASSERT(p->p_pptr != initproc);
+
+       KASSERT(ISSET(p->p_slflag, PSL_TRACED));
+       KASSERT(ISSET(p->p_slflag, PSL_SYSCALL));
+
+       p->p_xsig = signo;
+       p->p_sigctx.ps_lwp = ksi.ksi_lid;
+       p->p_sigctx.ps_info = ksi.ksi_info;
+       sigswitch(0, signo);
+       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);
        }
-
-       p->p_xsig = SIGTRAP;
-       p->p_sigctx.ps_info._signo = p->p_xsig;
-       p->p_sigctx.ps_info._code = trapno;
-       sigswitch(0, p->p_xsig);
-       mutex_exit(p->p_lock);
 }
 
 static int



Home | Main Index | Thread Index | Old Index