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