Make attach/detach more safe.
This commit is contained in:
parent
2bc213f176
commit
1815d82b85
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_sig.c,v 1.38 1994/12/14 19:07:12 mycroft Exp $ */
|
||||
/* $NetBSD: kern_sig.c,v 1.39 1995/02/03 11:35:57 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1991, 1993
|
||||
|
@ -923,14 +923,6 @@ issignal(p)
|
|||
} while (!trace_req(p) && p->p_flag & P_TRACED);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the traced bit got turned off, go back up
|
||||
* to the top to rescan signals. This ensures
|
||||
* that p_sig* and ps_sigact are consistent.
|
||||
*/
|
||||
if ((p->p_flag & P_TRACED) == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If parent wants us to take the signal,
|
||||
* then it will leave it in p->p_xstat;
|
||||
|
@ -947,7 +939,8 @@ issignal(p)
|
|||
*/
|
||||
mask = sigmask(signum);
|
||||
p->p_siglist |= mask;
|
||||
if (p->p_sigmask & mask)
|
||||
if ((p->p_flag & P_TRACED) == 0 ||
|
||||
(p->p_sigmask & mask) != 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sys_process.c,v 1.44 1995/01/26 17:56:21 mycroft Exp $ */
|
||||
/* $NetBSD: sys_process.c,v 1.45 1995/02/03 11:36:01 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1994 Christopher G. Demetriou. All rights reserved.
|
||||
|
@ -87,7 +87,7 @@ ptrace(p, uap, retval)
|
|||
struct proc *t; /* target process */
|
||||
struct uio uio;
|
||||
struct iovec iov;
|
||||
int error, step, write;
|
||||
int error, write;
|
||||
|
||||
/* "A foolish consistency..." XXX */
|
||||
if (SCARG(uap, req) == PT_TRACE_ME)
|
||||
|
@ -178,13 +178,14 @@ ptrace(p, uap, retval)
|
|||
FIX_SSTEP(t);
|
||||
|
||||
/* Now do the operation. */
|
||||
step = write = 0;
|
||||
write = 0;
|
||||
*retval = 0;
|
||||
|
||||
switch (SCARG(uap, req)) {
|
||||
case PT_TRACE_ME:
|
||||
/* Just set the trace flag. */
|
||||
SET(t->p_flag, P_TRACED);
|
||||
t->p_oppid = t->p_pptr->p_pid;
|
||||
return (0);
|
||||
|
||||
case PT_WRITE_I: /* XXX no seperate I and D spaces */
|
||||
|
@ -213,9 +214,9 @@ ptrace(p, uap, retval)
|
|||
* as soon as possible after execution of at least one
|
||||
* instruction, execution stops again. [ ... ]"
|
||||
*/
|
||||
step = 1;
|
||||
#endif
|
||||
case PT_CONTINUE:
|
||||
case PT_DETACH:
|
||||
/*
|
||||
* From the 4.4BSD PRM:
|
||||
* "The data argument is taken as a signal number and the
|
||||
|
@ -227,7 +228,6 @@ ptrace(p, uap, retval)
|
|||
* the stop. If addr is (int *)1 then execution continues
|
||||
* from where it stopped."
|
||||
*/
|
||||
/* step = 0 done above. */
|
||||
|
||||
/* Check that the data is a valid signal number or zero. */
|
||||
if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG)
|
||||
|
@ -236,7 +236,7 @@ ptrace(p, uap, retval)
|
|||
/*
|
||||
* Arrange for a single-step, if that's requested and possible.
|
||||
*/
|
||||
if (error = process_sstep(t, step))
|
||||
if (error = process_sstep(t, SCARG(uap, req) == PT_STEP))
|
||||
return (error);
|
||||
|
||||
/* If the address paramter is not (int *)1, set the pc. */
|
||||
|
@ -244,10 +244,29 @@ ptrace(p, uap, retval)
|
|||
if (error = process_set_pc(t, SCARG(uap, addr)))
|
||||
return (error);
|
||||
|
||||
if (SCARG(uap, req) == PT_DETACH) {
|
||||
/* give process back to original parent or init */
|
||||
if (t->p_oppid != t->p_pptr->p_pid) {
|
||||
struct proc *pp;
|
||||
|
||||
pp = pfind(t->p_oppid);
|
||||
proc_reparent(t, pp ? pp : initproc);
|
||||
}
|
||||
|
||||
/* not being traced any more */
|
||||
t->p_oppid = 0;
|
||||
CLR(t->p_flag, P_TRACED|P_WAITED);
|
||||
}
|
||||
|
||||
/* Finally, deliver the requested signal (or none). */
|
||||
sendsig:
|
||||
t->p_xstat = SCARG(uap, data);
|
||||
setrunnable(t);
|
||||
if (t->p_stat == SSTOP) {
|
||||
t->p_xstat = SCARG(uap, data);
|
||||
setrunnable(t);
|
||||
} else {
|
||||
if (SCARG(uap, data) != 0)
|
||||
psignal(t, SCARG(uap, data));
|
||||
}
|
||||
return (0);
|
||||
|
||||
case PT_KILL:
|
||||
|
@ -266,47 +285,13 @@ sendsig:
|
|||
* Stop the target.
|
||||
*/
|
||||
SET(t->p_flag, P_TRACED);
|
||||
t->p_xstat = 0; /* XXX ? */
|
||||
if (t->p_pptr != p) {
|
||||
t->p_oppid = t->p_pptr->p_pid;
|
||||
t->p_oppid = t->p_pptr->p_pid;
|
||||
if (t->p_pptr != p)
|
||||
proc_reparent(t, p);
|
||||
}
|
||||
t->p_xstat = 0; /* XXX ? */
|
||||
psignal(t, SIGSTOP);
|
||||
return (0);
|
||||
|
||||
case PT_DETACH:
|
||||
/* Again, as done in procfs: */
|
||||
|
||||
#ifdef notdef /* not allowed, by checks above. */
|
||||
/* if not being traced, then this is a painless no-op */
|
||||
if (!ISSET(t->p_flag, P_TRACED))
|
||||
return (0);
|
||||
#endif
|
||||
|
||||
/* not being traced any more */
|
||||
CLR(t->p_flag, P_TRACED);
|
||||
|
||||
/* give process back to original parent */
|
||||
if (t->p_oppid != t->p_pptr->p_pid) {
|
||||
struct proc *pp;
|
||||
|
||||
pp = pfind(t->p_oppid);
|
||||
if (pp)
|
||||
proc_reparent(t, pp);
|
||||
}
|
||||
|
||||
t->p_oppid = 0;
|
||||
CLR(t->p_flag, P_WAITED); /* XXX? */
|
||||
|
||||
/* and deliver any signal requested by tracer. */
|
||||
if (t->p_stat == SSTOP) {
|
||||
t->p_xstat = SCARG(uap, data);
|
||||
setrunnable(t);
|
||||
} else if (SCARG(uap, data))
|
||||
psignal(t, SCARG(uap, data));
|
||||
|
||||
return (0);
|
||||
|
||||
#ifdef PT_SETREGS
|
||||
case PT_SETREGS:
|
||||
write = 1;
|
||||
|
|
Loading…
Reference in New Issue