Source-Changes-HG archive

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

[src/trunk]: src/sys/compat Rework Mach exception and Darwin's ptrace. gdb is...



details:   https://anonhg.NetBSD.org/src/rev/2ebdcf152197
branches:  trunk
changeset: 556712:2ebdcf152197
user:      manu <manu%NetBSD.org@localhost>
date:      Wed Dec 24 23:22:22 2003 +0000

description:
Rework Mach exception and Darwin's ptrace. gdb is now able to attach a
remote process. This new implementation also passes all the test programs
I've written so far.

- When exceptions come from traps, no UNIX signal should evet be sent.
- Add a lock to ensure a debugger handles only one exception at a time
- Use a structure to hold flavor and behavior in exception ports, instead
  of stuffing the two argument into an int.
- Implement new Mach services: thread_suspend, thread_resume and thread_abort
- Implement Darwin's ptrace PT_ATTACHEXC and PT_THUPDATE commands
- Handle NULL second argument correctly in sigprocmask.
- One mistake in the last commit (darwin_tracesig prototype)

diffstat:

 sys/compat/darwin/darwin_ptrace.c     |  133 ++++++++++++++---------
 sys/compat/darwin/darwin_signal.c     |   62 ++++-------
 sys/compat/mach/mach_exception.c      |  188 ++++++++++++++++++++++-----------
 sys/compat/mach/mach_exception.h      |    6 +-
 sys/compat/mach/mach_exec.c           |   17 ++-
 sys/compat/mach/mach_exec.h           |    5 +-
 sys/compat/mach/mach_message.c        |    6 +-
 sys/compat/mach/mach_port.h           |    4 +-
 sys/compat/mach/mach_services.c       |   12 +-
 sys/compat/mach/mach_services.h       |    9 +-
 sys/compat/mach/mach_services.master  |    8 +-
 sys/compat/mach/mach_services_names.c |   12 +-
 sys/compat/mach/mach_task.c           |   29 +++-
 sys/compat/mach/mach_thread.c         |   63 +++++++++++-
 sys/compat/mach/mach_thread.h         |   41 +++++++-
 15 files changed, 402 insertions(+), 193 deletions(-)

diffs (truncated from 1103 to 300 lines):

diff -r 1b51b94c84f4 -r 2ebdcf152197 sys/compat/darwin/darwin_ptrace.c
--- a/sys/compat/darwin/darwin_ptrace.c Wed Dec 24 22:57:22 2003 +0000
+++ b/sys/compat/darwin/darwin_ptrace.c Wed Dec 24 23:22:22 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: darwin_ptrace.c,v 1.2 2003/12/04 23:59:50 manu Exp $ */
+/*     $NetBSD: darwin_ptrace.c,v 1.3 2003/12/24 23:22:22 manu Exp $ */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: darwin_ptrace.c,v 1.2 2003/12/04 23:59:50 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: darwin_ptrace.c,v 1.3 2003/12/24 23:22:22 manu Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -56,47 +56,8 @@
 #include <compat/darwin/darwin_ptrace.h>
 #include <compat/darwin/darwin_syscallargs.h>
 
-#if 0
 #define ISSET(t, f)     ((t) & (f))
 
-static inline int ptrace_sanity_check(struct proc *, struct proc *);
-
-/* Sanity checks copied from native sys_ptrace() */
-static inline int 
-ptrace_sanity_check(p, t)
-       struct proc *p;
-       struct proc *t;
-{
-       /*
-        * You can't do what you want to the process if:
-        *      (1) It's not being traced at all,
-        */
-       if (!ISSET(t->p_flag, P_TRACED))
-               return (EPERM);
-
-       /*
-        *      (2) it's being traced by procfs (which has
-        *          different signal delivery semantics),
-        */
-       if (ISSET(t->p_flag, P_FSTRACE))
-               return (EBUSY);
-
-       /*
-        *      (3) it's not being traced by _you_, or
-        */
-       if (t->p_pptr != p)
-               return (EBUSY);
-
-       /*
-        *      (4) it's not currently stopped.
-        */
-       if (t->p_stat != SSTOP || !ISSET(t->p_flag, P_WAITED))
-               return (EBUSY);
-
-       return 0;
-}
-#endif
-
 int
 darwin_sys_ptrace(l, v, retval)
        struct lwp *l;
@@ -115,32 +76,100 @@
        struct proc *t;                 /* target process */
        int error;
 
+       ded = (struct darwin_emuldata *)p->p_emuldata;
+
        switch (req) {
+       case DARWIN_PT_ATTACHEXC:
+               if ((t = pfind(SCARG(uap, pid))) == NULL)
+                       return ESRCH;
+
+               if (t->p_emul != &emul_darwin)
+                       return ESRCH;
+               ded = t->p_emuldata;
+
+               if (ded->ded_flags & DARWIN_DED_SIGEXC)
+                       return EBUSY;
+
+               ded->ded_flags |= DARWIN_DED_SIGEXC;
+
+               SCARG(uap, req) = PT_ATTACH;
+               if ((error = sys_ptrace(l, v, retval)) != 0)
+                        ded->ded_flags &= ~DARWIN_DED_SIGEXC;
+
+               return error;
+               break;
+               
        case DARWIN_PT_SIGEXC:
-               ded = (struct darwin_emuldata *)p->p_emuldata;
+               if ((p->p_flag & P_TRACED) == 0)
+                       return EBUSY;
+
                ded->ded_flags |= DARWIN_DED_SIGEXC;
                break;
 
-       case DARWIN_PT_DETACH:
+       case DARWIN_PT_DETACH: {
+               int had_sigexc = 0;
+
                if ((t = pfind(SCARG(uap, pid))) == NULL)
                        return (ESRCH);
 
-               /* 
-                * Clear signal-as-exceptions flag if detaching is 
-                * successful and if it is a Darwin process.
+               if ((t->p_emul == &emul_darwin) &&
+                   (t->p_flag & P_TRACED) &&
+                   (t->p_pptr == p)) {
+                       ded = t->p_emuldata;
+                       if (ded->ded_flags & DARWIN_DED_SIGEXC) {
+                               had_sigexc = 1;
+                               ded->ded_flags &= ~DARWIN_DED_SIGEXC;
+                       }
+               }
+
+               /*
+                * If the process is not marked as stopped, 
+                * sys_ptrace sanity checks will return EBUSY.
                 */
-               if (((error = sys_ptrace(l, v, retval)) == 0) &&
-                   (t->p_emul != &emul_darwin)) {
-                       ded = (struct darwin_emuldata *)t->p_emuldata;
-                       ded->ded_flags &= ~DARWIN_DED_SIGEXC;
+               proc_stop(t, 0);
+
+               if ((error = sys_ptrace(l, v, retval)) != 0) {
+                       proc_unstop(t);
+                       if (had_sigexc)
+                               ded->ded_flags |= DARWIN_DED_SIGEXC;
                }
+
                break;
+       }
+
+       case DARWIN_PT_THUPDATE: {
+               int signo = SCARG(uap, data);
+               
+               if ((t = pfind(SCARG(uap, pid))) == NULL)
+                       return ESRCH;
+
+               /* Checks from native ptrace */
+               if (!ISSET(t->p_flag, P_TRACED))
+                       return EPERM;
+
+               if (ISSET(t->p_flag, P_FSTRACE))
+                       return EBUSY;
+
+               if (t->p_pptr != p)
+                       return EBUSY;
+
+#if 0
+               if (t->p_stat != SSTOP || !ISSET(t->p_flag, P_WAITED))
+                       return EBUSY;
+#endif
+               if ((signo < 0) || (signo > NSIG))
+                       return EINVAL;
+
+               t->p_xstat = signo;
+               if (signo != 0)
+                       sigaddset(&p->p_sigctx.ps_siglist, signo);
+
+               break;          
+       }
 
        case DARWIN_PT_READ_U:
        case DARWIN_PT_WRITE_U:
        case DARWIN_PT_STEP:
-       case DARWIN_PT_THUPDATE:
-       case DARWIN_PT_ATTACHEXC:
        case DARWIN_PT_FORCEQUOTA:
        case DARWIN_PT_DENY_ATTACH:
                printf("darwin_sys_ptrace: unimplemented command %d\n", req);
diff -r 1b51b94c84f4 -r 2ebdcf152197 sys/compat/darwin/darwin_signal.c
--- a/sys/compat/darwin/darwin_signal.c Wed Dec 24 22:57:22 2003 +0000
+++ b/sys/compat/darwin/darwin_signal.c Wed Dec 24 23:22:22 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: darwin_signal.c,v 1.16 2003/12/24 22:57:22 manu Exp $ */
+/*     $NetBSD: darwin_signal.c,v 1.17 2003/12/24 23:22:22 manu Exp $ */
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: darwin_signal.c,v 1.16 2003/12/24 22:57:22 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: darwin_signal.c,v 1.17 2003/12/24 23:22:22 manu Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -138,48 +138,29 @@
 
 int
 darwin_tracesig(p, signo)
-       struct proc *l;
+       struct proc *p;
        int signo;
 {
-       struct proc *p = l->l_proc;
        struct darwin_emuldata *ded;
+       struct lwp *l;
        int code[2];
        int error;
-       int signo;
 
        /* 
-        * Don't generate Mach exeption for non 
-        * maskable, stop and continue signals 
-        */
-       if (sigprop[signo] & (SA_CANTMASK | SA_STOP | SA_CONT | SA_TTYSTOP))
-               return EINVAL;
-
-       /* Don't send an exception if the signal is masked or ignored */
-       if ((p->p_flag & P_TRACED) == 0) {
-               if ((sigismember(&p->p_sigctx.ps_sigignore, signo)) ||
-                   (sigismember(&p->p_sigctx.ps_sigmask, signo)))
-                       return EINVAL;
-       }
-
-       /* 
-        * Send signals as software exception if the process requested that.
+        * If the process does not have softsignals,
+        * we are done, normal signal delivery should 
+        * occur.
         */
        ded = (struct darwin_emuldata *)p->p_emuldata;
-       if (ded->ded_flags & DARWIN_DED_SIGEXC) {
-               code[0] = MACH_SOFT_SIGNAL;
-               code[1] = signo;
-               error = mach_exception(l, MACH_EXC_SOFTWARE, code);
+       if ((ded->ded_flags & DARWIN_DED_SIGEXC) == 0)
+               return 0;
 
-               /* Like if the signal was sent, wakeup any waiting process */
-               if ((error == 0) &&
-                   p->p_sigctx.ps_sigwaited &&
-                   sigismember(p->p_sigctx.ps_sigwait, signo) &&
-                   (p->p_stat != SSTOP))
-                       wakeup_one(&p->p_sigctx.ps_sigwait);
+       code[0] = MACH_SOFT_SIGNAL;
+       code[1] = signo;
+       l = proc_representative_lwp(p);
+       error = mach_exception(l, MACH_EXC_SOFTWARE, code);
 
-               return error;
-       }
-
+       /* Inhibit normal signal delivery */
        return EINVAL;
 }
 
@@ -199,7 +180,7 @@
        int error;
        sigset13_t kdset, kdoset;
        sigset_t kbset, kboset;
-       sigset_t *ubset;
+       sigset_t *ubset = NULL;
        sigset_t *uboset = NULL;
 
        caddr_t sg = stackgap_init(p, 0);
@@ -207,13 +188,16 @@
        if (SCARG(uap, oset) != NULL)
                uboset = stackgap_alloc(p, &sg, sizeof(*uboset));
        
-       if ((error = copyin(SCARG(uap, set), &kdset, sizeof(kdset))) != 0)
-               return error;
+       if (SCARG(uap, set) != NULL) {
+               error = copyin(SCARG(uap, set), &kdset, sizeof(kdset));
+               if (error != 0)
+                       return error;
 
-       native_sigset13_to_sigset(&kdset, &kbset);
+               native_sigset13_to_sigset(&kdset, &kbset);
 
-       if ((error = copyout(&kbset, ubset, sizeof(kbset))) != 0)
-               return error;
+               if ((error = copyout(&kbset, ubset, sizeof(kbset))) != 0)
+                       return error;
+       }
 
        SCARG(&cup, how) = SCARG(uap, how);
        SCARG(&cup, set) = ubset;
diff -r 1b51b94c84f4 -r 2ebdcf152197 sys/compat/mach/mach_exception.c
--- a/sys/compat/mach/mach_exception.c  Wed Dec 24 22:57:22 2003 +0000
+++ b/sys/compat/mach/mach_exception.c  Wed Dec 24 23:22:22 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mach_exception.c,v 1.1 2003/12/09 12:13:44 manu Exp $ */
+/*     $NetBSD: mach_exception.c,v 1.2 2003/12/24 23:22:22 manu Exp $ */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -37,9 +37,10 @@
  */
 



Home | Main Index | Thread Index | Old Index