summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2013-12-18 01:41:52 +0000
committermarkj <markj@FreeBSD.org>2013-12-18 01:41:52 +0000
commitfa6de9117d010d474939e5689c1d076d4918025b (patch)
tree6e1d82eccf41beda77ba33807668e571167cca32 /sys/cddl
parent2d61a75a7fed2c8b1a1480a43d3db460939839e1 (diff)
downloadFreeBSD-src-fa6de9117d010d474939e5689c1d076d4918025b.zip
FreeBSD-src-fa6de9117d010d474939e5689c1d076d4918025b.tar.gz
The fasttrap fork handler is responsible for removing tracepoints in the
child process that were inherited from its parent. However, this should not be done in the case of a vfork, since the fork handler ends up removing the tracepoints from the shared vm space, and userland DTrace probes in the parent will no longer fire as a result. Now the child of a vfork may trigger userland DTrace probes enabled in its parent, so modify the fasttrap probe handler to handle this case and handle the child process in the same way that it would handle the traced process. In particular, if once traces function foo() in a process that vforks, and the child calls foo(), fasttrap will treat this call as having come from the parent. This is the behaviour of the upstream code. While here, add #ifdef guards to some code that isn't present upstream. MFC after: 1 month
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c b/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
index c803a01..53ad33b 100644
--- a/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
+++ b/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
@@ -1001,6 +1001,9 @@ int
fasttrap_pid_probe(struct reg *rp)
{
proc_t *p = curproc;
+#if !defined(sun)
+ proc_t *pp;
+#endif
uintptr_t pc = rp->r_rip - 1;
uintptr_t new_pc = 0;
fasttrap_bucket_t *bucket;
@@ -1036,24 +1039,32 @@ fasttrap_pid_probe(struct reg *rp)
curthread->t_dtrace_regv = 0;
#endif
-#if defined(sun)
/*
* Treat a child created by a call to vfork(2) as if it were its
* parent. We know that there's only one thread of control in such a
* process: this one.
*/
+#if defined(sun)
while (p->p_flag & SVFORK) {
p = p->p_parent;
}
-#endif
- PROC_LOCK(p);
- _PHOLD(p);
pid = p->p_pid;
-#if defined(sun)
pid_mtx = &cpu_core[CPU->cpu_id].cpuc_pid_lock;
mutex_enter(pid_mtx);
+#else
+ pp = p;
+ sx_slock(&proctree_lock);
+ while (pp->p_vmspace == pp->p_pptr->p_vmspace)
+ pp = pp->p_pptr;
+ pid = pp->p_pid;
+ sx_sunlock(&proctree_lock);
+ pp = NULL;
+
+ PROC_LOCK(p);
+ _PHOLD(p);
#endif
+
bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)];
/*
@@ -1073,9 +1084,10 @@ fasttrap_pid_probe(struct reg *rp)
if (tp == NULL) {
#if defined(sun)
mutex_exit(pid_mtx);
-#endif
+#else
_PRELE(p);
PROC_UNLOCK(p);
+#endif
return (-1);
}
@@ -1197,9 +1209,10 @@ fasttrap_pid_probe(struct reg *rp)
* tracepoint again later if we need to light up any return probes.
*/
tp_local = *tp;
- PROC_UNLOCK(p);
#if defined(sun)
mutex_exit(pid_mtx);
+#else
+ PROC_UNLOCK(p);
#endif
tp = &tp_local;
@@ -1749,7 +1762,7 @@ fasttrap_pid_probe(struct reg *rp)
#if defined(sun)
if (fasttrap_copyout(scratch, (char *)addr, i)) {
#else
- if (uwrite(curproc, scratch, i, addr)) {
+ if (uwrite(p, scratch, i, addr)) {
#endif
fasttrap_sigtrap(p, curthread, pc);
new_pc = pc;
@@ -1808,10 +1821,12 @@ done:
rp->r_rip = new_pc;
+#if !defined(sun)
PROC_LOCK(p);
proc_write_regs(curthread, rp);
_PRELE(p);
PROC_UNLOCK(p);
+#endif
return (0);
}
OpenPOWER on IntegriCloud