Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/sys_process.c
Show First 20 Lines • Show All 687 Lines • ▼ Show 20 Lines | #define PROC_WRITE(w, t, a) wrap32 ? \ | ||||
(safe ? proc_write_ ## w ## 32(t, a) : EINVAL ) : \ | (safe ? proc_write_ ## w ## 32(t, a) : EINVAL ) : \ | ||||
proc_write_ ## w (t, a) | proc_write_ ## w (t, a) | ||||
#else | #else | ||||
#define PROC_READ(w, t, a) proc_read_ ## w (t, a) | #define PROC_READ(w, t, a) proc_read_ ## w (t, a) | ||||
#define PROC_WRITE(w, t, a) proc_write_ ## w (t, a) | #define PROC_WRITE(w, t, a) proc_write_ ## w (t, a) | ||||
#endif | #endif | ||||
void | void | ||||
proc_set_traced(struct proc *p) | proc_set_traced(struct proc *p, bool stop) | ||||
{ | { | ||||
PROC_LOCK_ASSERT(p, MA_OWNED); | PROC_LOCK_ASSERT(p, MA_OWNED); | ||||
p->p_flag |= P_TRACED; | p->p_flag |= P_TRACED; | ||||
if (stop) | |||||
p->p_flag2 |= P2_PTRACE_FSTP; | p->p_flag2 |= P2_PTRACE_FSTP; | ||||
p->p_ptevents = PTRACE_DEFAULT; | p->p_ptevents = PTRACE_DEFAULT; | ||||
p->p_oppid = p->p_pptr->p_pid; | p->p_oppid = p->p_pptr->p_pid; | ||||
} | } | ||||
int | int | ||||
kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) | kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) | ||||
{ | { | ||||
struct iovec iov; | struct iovec iov; | ||||
▲ Show 20 Lines • Show All 195 Lines • ▼ Show 20 Lines | #endif | ||||
* Actually do the requests | * Actually do the requests | ||||
*/ | */ | ||||
td->td_retval[0] = 0; | td->td_retval[0] = 0; | ||||
switch (req) { | switch (req) { | ||||
case PT_TRACE_ME: | case PT_TRACE_ME: | ||||
/* set my trace flag and "owner" so it can read/write me */ | /* set my trace flag and "owner" so it can read/write me */ | ||||
proc_set_traced(p); | proc_set_traced(p, false); | ||||
if (p->p_flag & P_PPWAIT) | if (p->p_flag & P_PPWAIT) | ||||
p->p_flag |= P_PPTRACE; | p->p_flag |= P_PPTRACE; | ||||
CTR1(KTR_PTRACE, "PT_TRACE_ME: pid %d", p->p_pid); | CTR1(KTR_PTRACE, "PT_TRACE_ME: pid %d", p->p_pid); | ||||
break; | break; | ||||
case PT_ATTACH: | case PT_ATTACH: | ||||
/* security check done above */ | /* security check done above */ | ||||
/* | /* | ||||
* It would be nice if the tracing relationship was separate | * It would be nice if the tracing relationship was separate | ||||
* from the parent relationship but that would require | * from the parent relationship but that would require | ||||
* another set of links in the proc struct or for "wait" | * another set of links in the proc struct or for "wait" | ||||
* to scan the entire proc table. To make life easier, | * to scan the entire proc table. To make life easier, | ||||
* we just re-parent the process we're trying to trace. | * we just re-parent the process we're trying to trace. | ||||
* The old parent is remembered so we can put things back | * The old parent is remembered so we can put things back | ||||
* on a "detach". | * on a "detach". | ||||
*/ | */ | ||||
proc_set_traced(p); | proc_set_traced(p, true); | ||||
if (p->p_pptr != td->td_proc) { | if (p->p_pptr != td->td_proc) { | ||||
proc_reparent(p, td->td_proc); | proc_reparent(p, td->td_proc); | ||||
} | } | ||||
data = SIGSTOP; | data = SIGSTOP; | ||||
CTR2(KTR_PTRACE, "PT_ATTACH: pid %d, oppid %d", p->p_pid, | CTR2(KTR_PTRACE, "PT_ATTACH: pid %d, oppid %d", p->p_pid, | ||||
p->p_oppid); | p->p_oppid); | ||||
goto sendsig; /* in PT_CONTINUE below */ | goto sendsig; /* in PT_CONTINUE below */ | ||||
▲ Show 20 Lines • Show All 511 Lines • Show Last 20 Lines |