Add KTR tracing for some MI ptrace events.
Differential Revision: https://reviews.freebsd.org/D2643 Reviewed by: kib
This commit is contained in:
parent
d707582f83
commit
515b7a0b97
@ -525,6 +525,8 @@ exit1(struct thread *td, int rv)
|
|||||||
*/
|
*/
|
||||||
while ((q = LIST_FIRST(&p->p_orphans)) != NULL) {
|
while ((q = LIST_FIRST(&p->p_orphans)) != NULL) {
|
||||||
PROC_LOCK(q);
|
PROC_LOCK(q);
|
||||||
|
CTR2(KTR_PTRACE, "exit: pid %d, clearing orphan %d", p->p_pid,
|
||||||
|
q->p_pid);
|
||||||
clear_orphan(q);
|
clear_orphan(q);
|
||||||
PROC_UNLOCK(q);
|
PROC_UNLOCK(q);
|
||||||
}
|
}
|
||||||
@ -857,6 +859,9 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options)
|
|||||||
t = proc_realparent(p);
|
t = proc_realparent(p);
|
||||||
PROC_LOCK(t);
|
PROC_LOCK(t);
|
||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
|
CTR2(KTR_PTRACE,
|
||||||
|
"wait: traced child %d moved back to parent %d", p->p_pid,
|
||||||
|
t->p_pid);
|
||||||
proc_reparent(p, t);
|
proc_reparent(p, t);
|
||||||
p->p_oppid = 0;
|
p->p_oppid = 0;
|
||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
@ -1216,6 +1221,10 @@ kern_wait6(struct thread *td, idtype_t idtype, id_t id, int *status,
|
|||||||
PROC_UNLOCK(q);
|
PROC_UNLOCK(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CTR4(KTR_PTRACE,
|
||||||
|
"wait: returning trapped pid %d status %#x (xstat %d) xthread %d",
|
||||||
|
p->p_pid, W_STOPCODE(p->p_xstat), p->p_xstat,
|
||||||
|
p->p_xthread != NULL ? p->p_xthread->td_tid : -1);
|
||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -1035,6 +1035,9 @@ fork_return(struct thread *td, struct trapframe *frame)
|
|||||||
dbg = p->p_pptr->p_pptr;
|
dbg = p->p_pptr->p_pptr;
|
||||||
p->p_flag |= P_TRACED;
|
p->p_flag |= P_TRACED;
|
||||||
p->p_oppid = p->p_pptr->p_pid;
|
p->p_oppid = p->p_pptr->p_pid;
|
||||||
|
CTR2(KTR_PTRACE,
|
||||||
|
"fork_return: attaching to new child pid %d: oppid %d",
|
||||||
|
p->p_pid, p->p_oppid);
|
||||||
proc_reparent(p, dbg);
|
proc_reparent(p, dbg);
|
||||||
sx_xunlock(&proctree_lock);
|
sx_xunlock(&proctree_lock);
|
||||||
td->td_dbgflags |= TDB_CHILD;
|
td->td_dbgflags |= TDB_CHILD;
|
||||||
|
@ -2478,6 +2478,8 @@ ptracestop(struct thread *td, int sig)
|
|||||||
|
|
||||||
td->td_dbgflags |= TDB_XSIG;
|
td->td_dbgflags |= TDB_XSIG;
|
||||||
td->td_xsig = sig;
|
td->td_xsig = sig;
|
||||||
|
CTR4(KTR_PTRACE, "ptracestop: tid %d (pid %d) flags %#x sig %d",
|
||||||
|
td->td_tid, p->p_pid, td->td_dbgflags, sig);
|
||||||
PROC_SLOCK(p);
|
PROC_SLOCK(p);
|
||||||
while ((p->p_flag & P_TRACED) && (td->td_dbgflags & TDB_XSIG)) {
|
while ((p->p_flag & P_TRACED) && (td->td_dbgflags & TDB_XSIG)) {
|
||||||
if (p->p_flag & P_SINGLE_EXIT) {
|
if (p->p_flag & P_SINGLE_EXIT) {
|
||||||
|
@ -432,6 +432,9 @@ ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
|
|||||||
free(freepath, M_TEMP);
|
free(freepath, M_TEMP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (error == 0)
|
||||||
|
CTR3(KTR_PTRACE, "PT_VM_ENTRY: pid %d, entry %d, start %p",
|
||||||
|
p->p_pid, pve->pve_entry, pve->pve_start);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
@ -826,6 +829,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||||||
if (p->p_flag & P_PPWAIT)
|
if (p->p_flag & P_PPWAIT)
|
||||||
p->p_flag |= P_PPTRACE;
|
p->p_flag |= P_PPTRACE;
|
||||||
p->p_oppid = p->p_pptr->p_pid;
|
p->p_oppid = p->p_pptr->p_pid;
|
||||||
|
CTR1(KTR_PTRACE, "PT_TRACE_ME: pid %d", p->p_pid);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_ATTACH:
|
case PT_ATTACH:
|
||||||
@ -845,17 +849,25 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||||||
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,
|
||||||
|
p->p_oppid);
|
||||||
goto sendsig; /* in PT_CONTINUE below */
|
goto sendsig; /* in PT_CONTINUE below */
|
||||||
|
|
||||||
case PT_CLEARSTEP:
|
case PT_CLEARSTEP:
|
||||||
|
CTR2(KTR_PTRACE, "PT_CLEARSTEP: tid %d (pid %d)", td2->td_tid,
|
||||||
|
p->p_pid);
|
||||||
error = ptrace_clear_single_step(td2);
|
error = ptrace_clear_single_step(td2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_SETSTEP:
|
case PT_SETSTEP:
|
||||||
|
CTR2(KTR_PTRACE, "PT_SETSTEP: tid %d (pid %d)", td2->td_tid,
|
||||||
|
p->p_pid);
|
||||||
error = ptrace_single_step(td2);
|
error = ptrace_single_step(td2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_SUSPEND:
|
case PT_SUSPEND:
|
||||||
|
CTR2(KTR_PTRACE, "PT_SUSPEND: tid %d (pid %d)", td2->td_tid,
|
||||||
|
p->p_pid);
|
||||||
td2->td_dbgflags |= TDB_SUSPEND;
|
td2->td_dbgflags |= TDB_SUSPEND;
|
||||||
thread_lock(td2);
|
thread_lock(td2);
|
||||||
td2->td_flags |= TDF_NEEDSUSPCHK;
|
td2->td_flags |= TDF_NEEDSUSPCHK;
|
||||||
@ -863,10 +875,15 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_RESUME:
|
case PT_RESUME:
|
||||||
|
CTR2(KTR_PTRACE, "PT_RESUME: tid %d (pid %d)", td2->td_tid,
|
||||||
|
p->p_pid);
|
||||||
td2->td_dbgflags &= ~TDB_SUSPEND;
|
td2->td_dbgflags &= ~TDB_SUSPEND;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_FOLLOW_FORK:
|
case PT_FOLLOW_FORK:
|
||||||
|
CTR3(KTR_PTRACE, "PT_FOLLOW_FORK: pid %d %s -> %s", p->p_pid,
|
||||||
|
p->p_flag & P_FOLLOWFORK ? "enabled" : "disabled",
|
||||||
|
data ? "enabled" : "disabled");
|
||||||
if (data)
|
if (data)
|
||||||
p->p_flag |= P_FOLLOWFORK;
|
p->p_flag |= P_FOLLOWFORK;
|
||||||
else
|
else
|
||||||
@ -887,6 +904,8 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||||||
|
|
||||||
switch (req) {
|
switch (req) {
|
||||||
case PT_STEP:
|
case PT_STEP:
|
||||||
|
CTR2(KTR_PTRACE, "PT_STEP: tid %d (pid %d)",
|
||||||
|
td2->td_tid, p->p_pid);
|
||||||
error = ptrace_single_step(td2);
|
error = ptrace_single_step(td2);
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
@ -904,12 +923,25 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||||||
switch (req) {
|
switch (req) {
|
||||||
case PT_TO_SCE:
|
case PT_TO_SCE:
|
||||||
p->p_stops |= S_PT_SCE;
|
p->p_stops |= S_PT_SCE;
|
||||||
|
CTR2(KTR_PTRACE,
|
||||||
|
"PT_TO_SCE: pid %d, stops = %#x", p->p_pid,
|
||||||
|
p->p_stops);
|
||||||
break;
|
break;
|
||||||
case PT_TO_SCX:
|
case PT_TO_SCX:
|
||||||
p->p_stops |= S_PT_SCX;
|
p->p_stops |= S_PT_SCX;
|
||||||
|
CTR2(KTR_PTRACE,
|
||||||
|
"PT_TO_SCX: pid %d, stops = %#x", p->p_pid,
|
||||||
|
p->p_stops);
|
||||||
break;
|
break;
|
||||||
case PT_SYSCALL:
|
case PT_SYSCALL:
|
||||||
p->p_stops |= S_PT_SCE | S_PT_SCX;
|
p->p_stops |= S_PT_SCE | S_PT_SCX;
|
||||||
|
CTR2(KTR_PTRACE,
|
||||||
|
"PT_SYSCALL: pid %d, stops = %#x", p->p_pid,
|
||||||
|
p->p_stops);
|
||||||
|
break;
|
||||||
|
case PT_CONTINUE:
|
||||||
|
CTR1(KTR_PTRACE,
|
||||||
|
"PT_CONTINUE: pid %d", p->p_pid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -924,7 +956,11 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||||||
proc_reparent(p, pp);
|
proc_reparent(p, pp);
|
||||||
if (pp == initproc)
|
if (pp == initproc)
|
||||||
p->p_sigparent = SIGCHLD;
|
p->p_sigparent = SIGCHLD;
|
||||||
}
|
CTR2(KTR_PTRACE,
|
||||||
|
"PT_DETACH: pid %d reparented to pid %d",
|
||||||
|
p->p_pid, pp->p_pid);
|
||||||
|
} else
|
||||||
|
CTR1(KTR_PTRACE, "PT_DETACH: pid %d", p->p_pid);
|
||||||
p->p_oppid = 0;
|
p->p_oppid = 0;
|
||||||
p->p_flag &= ~(P_TRACED | P_WAITED | P_FOLLOWFORK);
|
p->p_flag &= ~(P_TRACED | P_WAITED | P_FOLLOWFORK);
|
||||||
|
|
||||||
@ -1001,6 +1037,14 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||||||
}
|
}
|
||||||
if (!write)
|
if (!write)
|
||||||
td->td_retval[0] = tmp;
|
td->td_retval[0] = tmp;
|
||||||
|
if (error == 0) {
|
||||||
|
if (write)
|
||||||
|
CTR3(KTR_PTRACE, "PT_WRITE: pid %d: %p <= %#x",
|
||||||
|
p->p_pid, addr, data);
|
||||||
|
else
|
||||||
|
CTR3(KTR_PTRACE, "PT_READ: pid %d: %p >= %#x",
|
||||||
|
p->p_pid, addr, tmp);
|
||||||
|
}
|
||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1033,10 +1077,14 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||||||
switch (tmp) {
|
switch (tmp) {
|
||||||
case PIOD_READ_D:
|
case PIOD_READ_D:
|
||||||
case PIOD_READ_I:
|
case PIOD_READ_I:
|
||||||
|
CTR3(KTR_PTRACE, "PT_IO: pid %d: READ (%p, %#x)",
|
||||||
|
p->p_pid, (uintptr_t)uio.uio_offset, uio.uio_resid);
|
||||||
uio.uio_rw = UIO_READ;
|
uio.uio_rw = UIO_READ;
|
||||||
break;
|
break;
|
||||||
case PIOD_WRITE_D:
|
case PIOD_WRITE_D:
|
||||||
case PIOD_WRITE_I:
|
case PIOD_WRITE_I:
|
||||||
|
CTR3(KTR_PTRACE, "PT_IO: pid %d: WRITE (%p, %#x)",
|
||||||
|
p->p_pid, (uintptr_t)uio.uio_offset, uio.uio_resid);
|
||||||
td2->td_dbgflags |= TDB_USERWR;
|
td2->td_dbgflags |= TDB_USERWR;
|
||||||
uio.uio_rw = UIO_WRITE;
|
uio.uio_rw = UIO_WRITE;
|
||||||
break;
|
break;
|
||||||
@ -1056,33 +1104,46 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_KILL:
|
case PT_KILL:
|
||||||
|
CTR1(KTR_PTRACE, "PT_KILL: pid %d", p->p_pid);
|
||||||
data = SIGKILL;
|
data = SIGKILL;
|
||||||
goto sendsig; /* in PT_CONTINUE above */
|
goto sendsig; /* in PT_CONTINUE above */
|
||||||
|
|
||||||
case PT_SETREGS:
|
case PT_SETREGS:
|
||||||
|
CTR2(KTR_PTRACE, "PT_SETREGS: tid %d (pid %d)", td2->td_tid,
|
||||||
|
p->p_pid);
|
||||||
td2->td_dbgflags |= TDB_USERWR;
|
td2->td_dbgflags |= TDB_USERWR;
|
||||||
error = PROC_WRITE(regs, td2, addr);
|
error = PROC_WRITE(regs, td2, addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_GETREGS:
|
case PT_GETREGS:
|
||||||
|
CTR2(KTR_PTRACE, "PT_GETREGS: tid %d (pid %d)", td2->td_tid,
|
||||||
|
p->p_pid);
|
||||||
error = PROC_READ(regs, td2, addr);
|
error = PROC_READ(regs, td2, addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_SETFPREGS:
|
case PT_SETFPREGS:
|
||||||
|
CTR2(KTR_PTRACE, "PT_SETFPREGS: tid %d (pid %d)", td2->td_tid,
|
||||||
|
p->p_pid);
|
||||||
td2->td_dbgflags |= TDB_USERWR;
|
td2->td_dbgflags |= TDB_USERWR;
|
||||||
error = PROC_WRITE(fpregs, td2, addr);
|
error = PROC_WRITE(fpregs, td2, addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_GETFPREGS:
|
case PT_GETFPREGS:
|
||||||
|
CTR2(KTR_PTRACE, "PT_GETFPREGS: tid %d (pid %d)", td2->td_tid,
|
||||||
|
p->p_pid);
|
||||||
error = PROC_READ(fpregs, td2, addr);
|
error = PROC_READ(fpregs, td2, addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_SETDBREGS:
|
case PT_SETDBREGS:
|
||||||
|
CTR2(KTR_PTRACE, "PT_SETDBREGS: tid %d (pid %d)", td2->td_tid,
|
||||||
|
p->p_pid);
|
||||||
td2->td_dbgflags |= TDB_USERWR;
|
td2->td_dbgflags |= TDB_USERWR;
|
||||||
error = PROC_WRITE(dbregs, td2, addr);
|
error = PROC_WRITE(dbregs, td2, addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_GETDBREGS:
|
case PT_GETDBREGS:
|
||||||
|
CTR2(KTR_PTRACE, "PT_GETDBREGS: tid %d (pid %d)", td2->td_tid,
|
||||||
|
p->p_pid);
|
||||||
error = PROC_READ(dbregs, td2, addr);
|
error = PROC_READ(dbregs, td2, addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1145,13 +1206,21 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||||||
if (wrap32)
|
if (wrap32)
|
||||||
ptrace_lwpinfo_to32(pl, pl32);
|
ptrace_lwpinfo_to32(pl, pl32);
|
||||||
#endif
|
#endif
|
||||||
|
CTR5(KTR_PTRACE,
|
||||||
|
"PT_LWPINFO: tid %d (pid %d) event %d flags %#x child pid %d",
|
||||||
|
td2->td_tid, p->p_pid, pl->pl_event, pl->pl_flags,
|
||||||
|
pl->pl_child_pid);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_GETNUMLWPS:
|
case PT_GETNUMLWPS:
|
||||||
|
CTR2(KTR_PTRACE, "PT_GETNUMLWPS: pid %d: %d threads", p->p_pid,
|
||||||
|
p->p_numthreads);
|
||||||
td->td_retval[0] = p->p_numthreads;
|
td->td_retval[0] = p->p_numthreads;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_GETLWPLIST:
|
case PT_GETLWPLIST:
|
||||||
|
CTR3(KTR_PTRACE, "PT_GETLWPLIST: pid %d: data %d, actual %d",
|
||||||
|
p->p_pid, data, p->p_numthreads);
|
||||||
if (data <= 0) {
|
if (data <= 0) {
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
break;
|
break;
|
||||||
@ -1175,6 +1244,8 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_VM_TIMESTAMP:
|
case PT_VM_TIMESTAMP:
|
||||||
|
CTR2(KTR_PTRACE, "PT_VM_TIMESTAMP: pid %d: timestamp %d",
|
||||||
|
p->p_pid, p->p_vmspace->vm_map.timestamp);
|
||||||
td->td_retval[0] = p->p_vmspace->vm_map.timestamp;
|
td->td_retval[0] = p->p_vmspace->vm_map.timestamp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1225,6 +1296,8 @@ stopevent(struct proc *p, unsigned int event, unsigned int val)
|
|||||||
|
|
||||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||||
p->p_step = 1;
|
p->p_step = 1;
|
||||||
|
CTR3(KTR_PTRACE, "stopevent: pid %d event %u val %u", p->p_pid, event,
|
||||||
|
val);
|
||||||
do {
|
do {
|
||||||
p->p_xstat = val;
|
p->p_xstat = val;
|
||||||
p->p_xthread = NULL;
|
p->p_xthread = NULL;
|
||||||
|
@ -71,7 +71,8 @@
|
|||||||
#define KTR_INET6 0x10000000 /* IPv6 stack */
|
#define KTR_INET6 0x10000000 /* IPv6 stack */
|
||||||
#define KTR_SCHED 0x20000000 /* Machine parsed sched info. */
|
#define KTR_SCHED 0x20000000 /* Machine parsed sched info. */
|
||||||
#define KTR_BUF 0x40000000 /* Buffer cache */
|
#define KTR_BUF 0x40000000 /* Buffer cache */
|
||||||
#define KTR_ALL 0x7fffffff
|
#define KTR_PTRACE 0x80000000 /* Process debugging. */
|
||||||
|
#define KTR_ALL 0xffffffff
|
||||||
|
|
||||||
/* KTR trace classes to compile in */
|
/* KTR trace classes to compile in */
|
||||||
#ifdef KTR
|
#ifdef KTR
|
||||||
|
Loading…
Reference in New Issue
Block a user