Source-Changes-HG archive

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

[src/trunk]: src/sys kern/5201{2,8,9}: Fix PT_SYSCALL stopping.



details:   https://anonhg.NetBSD.org/src/rev/d28250048d63
branches:  trunk
changeset: 822523:d28250048d63
user:      christos <christos%NetBSD.org@localhost>
date:      Thu Mar 23 21:59:54 2017 +0000

description:
kern/5201{2,8,9}: Fix PT_SYSCALL stopping.
1. Supply the siginfo we expect TRAP_SC{E,X} to process_stoptrace() and set it.
2. Change the second argument of proc_stop from notify, to now meaning that
   we want to stop right now. Wait in process_stoptrace until that has happened.
3. While here, fix the locking order in process_stoptrace().

diffstat:

 sys/kern/kern_sig.c     |  16 ++++++----------
 sys/kern/kern_syscall.c |  11 ++++++-----
 sys/kern/sys_process.c  |  18 ++++++++++++++----
 sys/sys/ptrace.h        |   4 ++--
 4 files changed, 28 insertions(+), 21 deletions(-)

diffs (173 lines):

diff -r 7cebdfc3f3b8 -r d28250048d63 sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c       Thu Mar 23 18:27:29 2017 +0000
+++ b/sys/kern/kern_sig.c       Thu Mar 23 21:59:54 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_sig.c,v 1.332 2017/01/06 22:53:17 kamil Exp $     */
+/*     $NetBSD: kern_sig.c,v 1.333 2017/03/23 21:59:55 christos 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.332 2017/01/06 22:53:17 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.333 2017/03/23 21:59:55 christos Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_dtrace.h"
@@ -1535,7 +1535,7 @@
         */
        if (p->p_stat == SACTIVE && (p->p_sflag & PS_STOPPING) == 0) {
                KASSERT(signo != 0);
-               proc_stop(p, 1, signo);
+               proc_stop(p, 0, signo);
                KASSERT(p->p_nrlwps > 0);
        }
 
@@ -2099,7 +2099,7 @@
  * Put process 'p' into the stopped state and optionally, notify the parent.
  */
 void
-proc_stop(struct proc *p, int notify, int signo)
+proc_stop(struct proc *p, int now, int signo)
 {
        struct lwp *l;
 
@@ -2110,11 +2110,7 @@
         * LWPs to a halt so they are included in p->p_nrlwps.  We musn't
         * unlock between here and the p->p_nrlwps check below.
         */
-       p->p_sflag |= PS_STOPPING;
-       if (notify)
-               p->p_sflag |= PS_NOTIFYSTOP;
-       else
-               p->p_sflag &= ~PS_NOTIFYSTOP;
+       p->p_sflag |= PS_STOPPING | PS_NOTIFYSTOP;
        membar_producer();
 
        proc_stop_lwps(p);
@@ -2125,7 +2121,7 @@
         * LWP to stop will take care of it.
         */
 
-       if (p->p_nrlwps == 0) {
+       if (p->p_nrlwps == 0 || (now && p->p_nrlwps == 1 && p == curproc)) {
                proc_stop_done(p, true, PS_NOCLDSTOP);
        } else {
                /*
diff -r 7cebdfc3f3b8 -r d28250048d63 sys/kern/kern_syscall.c
--- a/sys/kern/kern_syscall.c   Thu Mar 23 18:27:29 2017 +0000
+++ b/sys/kern/kern_syscall.c   Thu Mar 23 21:59:54 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_syscall.c,v 1.14 2015/11/30 23:34:47 pgoyette Exp $       */
+/*     $NetBSD: kern_syscall.c,v 1.15 2017/03/23 21:59:55 christos Exp $       */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_syscall.c,v 1.14 2015/11/30 23:34:47 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_syscall.c,v 1.15 2017/03/23 21:59:55 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_modular.h"
@@ -248,7 +248,7 @@
 #ifdef PTRACE
        if ((curlwp->l_proc->p_slflag & (PSL_SYSCALL|PSL_TRACED)) ==
            (PSL_SYSCALL|PSL_TRACED)) {
-               process_stoptrace();
+               process_stoptrace(TRAP_SCE);
                if (curlwp->l_proc->p_slflag & PSL_SYSCALLEMU) {
                        /* tracer will emulate syscall for us */
                        error = EJUSTRETURN;
@@ -288,8 +288,9 @@
        
 #ifdef PTRACE
        if ((p->p_slflag & (PSL_SYSCALL|PSL_TRACED|PSL_SYSCALLEMU)) ==
-           (PSL_SYSCALL|PSL_TRACED))
-               process_stoptrace();
+           (PSL_SYSCALL|PSL_TRACED)) {
+               process_stoptrace(TRAP_SCX);
+       }
        CLR(p->p_slflag, PSL_SYSCALLEMU);
 #endif
 }
diff -r 7cebdfc3f3b8 -r d28250048d63 sys/kern/sys_process.c
--- a/sys/kern/sys_process.c    Thu Mar 23 18:27:29 2017 +0000
+++ b/sys/kern/sys_process.c    Thu Mar 23 21:59:54 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_process.c,v 1.176 2017/03/22 22:11:47 skrll Exp $  */
+/*     $NetBSD: sys_process.c,v 1.177 2017/03/23 21:59:55 christos Exp $       */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -118,7 +118,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.176 2017/03/22 22:11:47 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.177 2017/03/23 21:59:55 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ptrace.h"
@@ -187,13 +187,13 @@
 }
 
 void
-process_stoptrace(void)
+process_stoptrace(int trapno)
 {
        struct lwp *l = curlwp;
        struct proc *p = l->l_proc, *pp;
 
+       mutex_enter(p->p_lock);
        mutex_enter(proc_lock);
-       mutex_enter(p->p_lock);
        pp = p->p_pptr;
        if (pp->p_pid == 1) {
                CLR(p->p_slflag, PSL_SYSCALL);  /* XXXSMP */
@@ -202,6 +202,8 @@
                return;
        }
 
+       p->p_sigctx.ps_info._signo = SIGTRAP;
+       p->p_sigctx.ps_info._code = trapno;
        p->p_xsig = SIGTRAP;
        proc_stop(p, 1, SIGSTOP);
        mutex_exit(proc_lock);
@@ -211,6 +213,14 @@
                l->l_flag |= LW_PENDSIG;
                lwp_unlock(l);
        }
+       /* Switch and wait until we come to a stop */
+       do {
+               mutex_exit(p->p_lock);
+               lwp_lock(l);
+               mi_switch(l);
+               mutex_enter(p->p_lock);
+       } while (p->p_sflag & PS_STOPPING);
+
        mutex_exit(p->p_lock);
 }
 #endif /* KTRACE || PTRACE_HOOKS */
diff -r 7cebdfc3f3b8 -r d28250048d63 sys/sys/ptrace.h
--- a/sys/sys/ptrace.h  Thu Mar 23 18:27:29 2017 +0000
+++ b/sys/sys/ptrace.h  Thu Mar 23 21:59:54 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ptrace.h,v 1.58 2017/02/23 03:34:23 kamil Exp $        */
+/*     $NetBSD: ptrace.h,v 1.59 2017/03/23 21:59:54 christos Exp $     */
 
 /*-
  * Copyright (c) 1984, 1993
@@ -208,7 +208,7 @@
 
 int    process_domem(struct lwp *, struct lwp *, struct uio *);
 
-void   process_stoptrace(void);
+void   process_stoptrace(int);
 
 void   proc_reparent(struct proc *, struct proc *);
 void   proc_changeparent(struct proc *, struct proc *);



Home | Main Index | Thread Index | Old Index