changeset 1880:1982c224f2bd onnv_39

6410027 ustack() on x86 doesn't match pstack(1) 6414721 it should be legal to have only is-enabled probes 6414729 USDT probes can't be enabled during fork 6414734 $dtrace... symbols appear for static functions containing USDT probes 6414740 processes without DTrace privileges don't auto-enable their USDT probes 6415612 core section headers can be corrupt 6415617 USDT providers with identical names can cause an assertion failure
author ahl
date Mon, 24 Apr 2006 21:11:42 -0700
parents ebbc677f4973
children 91880172d596
files usr/src/lib/libdtrace/common/dt_dof.c usr/src/lib/libproc/common/Psymtab.c usr/src/uts/common/dtrace/dtrace.c usr/src/uts/common/dtrace/fasttrap.c usr/src/uts/common/exec/elf/elf.c usr/src/uts/common/os/dtrace_subr.c usr/src/uts/common/os/fork.c usr/src/uts/common/sys/fasttrap_impl.h usr/src/uts/common/sys/proc.h usr/src/uts/intel/dtrace/dtrace_isa.c
diffstat 10 files changed, 153 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/libdtrace/common/dt_dof.c	Mon Apr 24 19:31:54 2006 -0700
+++ b/usr/src/lib/libdtrace/common/dt_dof.c	Mon Apr 24 21:11:42 2006 -0700
@@ -440,7 +440,12 @@
 
 		dofpr.dofpr_func = dof_add_string(ddo, pip->pi_fname);
 
-		assert(pip->pi_noffs > 0);
+		/*
+		 * There should be one probe offset or is-enabled probe offset
+		 * or else this probe instance won't have been created. The
+		 * kernel will reject DOF which has a probe with no offsets.
+		 */
+		assert(pip->pi_noffs + pip->pi_nenoffs > 0);
 
 		dofpr.dofpr_offidx =
 		    dt_buf_len(&ddo->ddo_offs) / sizeof (uint32_t);
@@ -487,6 +492,7 @@
 	dof_relohdr_t dofr;
 	dof_secidx_t *dofs;
 	ulong_t xr, nxr;
+	size_t sz;
 	id_t i;
 
 	if (pvp->pv_flags & DT_PROVIDER_IMPL)
@@ -529,15 +535,17 @@
 
 	dt_buf_concat(dtp, &ddo->ddo_ldata, &ddo->ddo_args, sizeof (uint8_t));
 
-	assert(dt_buf_len(&ddo->ddo_offs) > 0);
-
 	dofpv.dofpv_proffs = dof_add_lsect(ddo, NULL, DOF_SECT_PROFFS,
 	    sizeof (uint_t), 0, sizeof (uint_t), dt_buf_len(&ddo->ddo_offs));
 
 	dt_buf_concat(dtp, &ddo->ddo_ldata, &ddo->ddo_offs, sizeof (uint_t));
 
-	dofpv.dofpv_prenoffs = dof_add_lsect(ddo, NULL, DOF_SECT_PRENOFFS,
-	    sizeof (uint_t), 0, sizeof (uint_t), dt_buf_len(&ddo->ddo_enoffs));
+	if ((sz = dt_buf_len(&ddo->ddo_enoffs)) != 0) {
+		dofpv.dofpv_prenoffs = dof_add_lsect(ddo, NULL,
+		    DOF_SECT_PRENOFFS, sizeof (uint_t), 0, sizeof (uint_t), sz);
+	} else {
+		dofpv.dofpv_prenoffs = DOF_SECT_NONE;
+	}
 
 	dt_buf_concat(dtp, &ddo->ddo_ldata, &ddo->ddo_enoffs, sizeof (uint_t));
 
--- a/usr/src/lib/libproc/common/Psymtab.c	Mon Apr 24 19:31:54 2006 -0700
+++ b/usr/src/lib/libproc/common/Psymtab.c	Mon Apr 24 21:11:42 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -2003,6 +2003,15 @@
 	}
 
 	/*
+	 * Prefer the symbol that doesn't begin with a '$' since compilers and
+	 * other symbol generators often use it as a prefix.
+	 */
+	if (*bname == '$')
+		return (-1);
+	if (*aname == '$')
+		return (1);
+
+	/*
 	 * Prefer the name with fewer leading underscores in the name.
 	 */
 	while (*aname == '_' && *bname == '_') {
--- a/usr/src/uts/common/dtrace/dtrace.c	Mon Apr 24 19:31:54 2006 -0700
+++ b/usr/src/uts/common/dtrace/dtrace.c	Mon Apr 24 21:11:42 2006 -0700
@@ -5537,11 +5537,15 @@
 {
 	uint32_t priv;
 
-	*uidp = crgetuid(cr);
-	*zoneidp = crgetzoneid(cr);
-	if (PRIV_POLICY_ONLY(cr, PRIV_ALL, B_FALSE)) {
+	if (cr == NULL || PRIV_POLICY_ONLY(cr, PRIV_ALL, B_FALSE)) {
+		/*
+		 * For DTRACE_PRIV_ALL, the uid and zoneid don't matter.
+		 */
 		priv = DTRACE_PRIV_ALL;
 	} else {
+		*uidp = crgetuid(cr);
+		*zoneidp = crgetzoneid(cr);
+
 		priv = 0;
 		if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_KERNEL, B_FALSE))
 			priv |= DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER;
@@ -6636,7 +6640,8 @@
 	}
 
 	dtrace_probekey(desc, &pkey);
-	dtrace_cred2priv(CRED(), &priv, &uid, &zoneid);
+	dtrace_cred2priv(enab->dten_vstate->dtvs_state->dts_cred.dcr_cred,
+	    &priv, &uid, &zoneid);
 
 	return (dtrace_match(&pkey, priv, uid, zoneid, dtrace_ecb_create_enable,
 	    enab));
@@ -6707,7 +6712,7 @@
 	 * See dtrace_helper_provider_validate().
 	 */
 	if (dof->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_1 &&
-	    provider->dofpv_prenoffs != 0) {
+	    provider->dofpv_prenoffs != DOF_SECT_NONE) {
 		enoff_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff +
 		    provider->dofpv_prenoffs * dof->dofh_secsize);
 		enoff = (uint32_t *)(uintptr_t)(daddr + enoff_sec->dofs_offset);
@@ -12581,8 +12586,9 @@
 	enoff_sec = NULL;
 
 	if (dof->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_1 &&
-	    provider->dofpv_prenoffs != 0 && (enoff_sec = dtrace_dof_sect(dof,
-	    DOF_SECT_PRENOFFS, provider->dofpv_prenoffs)) == NULL)
+	    provider->dofpv_prenoffs != DOF_SECT_NONE &&
+	    (enoff_sec = dtrace_dof_sect(dof, DOF_SECT_PRENOFFS,
+	    provider->dofpv_prenoffs)) == NULL)
 		return (-1);
 
 	strtab = (char *)(uintptr_t)(daddr + str_sec->dofs_offset);
@@ -12647,11 +12653,10 @@
 		}
 
 		/*
-		 * The offset count must not wrap the index and there must be
-		 * at least one offset. The offsets must also not overflow the
-		 * section's data.
-		 */
-		if (probe->dofpr_offidx + probe->dofpr_noffs <=
+		 * The offset count must not wrap the index, and the offsets
+		 * must also not overflow the section's data.
+		 */
+		if (probe->dofpr_offidx + probe->dofpr_noffs <
 		    probe->dofpr_offidx ||
 		    (probe->dofpr_offidx + probe->dofpr_noffs) *
 		    off_sec->dofs_entsize > off_sec->dofs_size) {
@@ -12664,8 +12669,7 @@
 			 * If there's no is-enabled offset section, make sure
 			 * there aren't any is-enabled offsets. Otherwise
 			 * perform the same checks as for probe offsets
-			 * (immediately above), except that having zero
-			 * is-enabled offsets is permitted.
+			 * (immediately above).
 			 */
 			if (enoff_sec == NULL) {
 				if (probe->dofpr_enoffidx != 0 ||
@@ -12682,6 +12686,15 @@
 				    "offset");
 				return (-1);
 			}
+
+			if (probe->dofpr_noffs + probe->dofpr_nenoffs == 0) {
+				dtrace_dof_error(dof, "zero probe and "
+				    "is-enabled offsets");
+				return (-1);
+			}
+		} else if (probe->dofpr_noffs == 0) {
+			dtrace_dof_error(dof, "zero probe offsets");
+			return (-1);
 		}
 
 		if (probe->dofpr_argidx + probe->dofpr_xargc <
--- a/usr/src/uts/common/dtrace/fasttrap.c	Mon Apr 24 19:31:54 2006 -0700
+++ b/usr/src/uts/common/dtrace/fasttrap.c	Mon Apr 24 21:11:42 2006 -0700
@@ -298,7 +298,8 @@
 				 * modified, we can't unregister or even
 				 * condense.
 				 */
-				if (fp->ftp_ccount != 0) {
+				if (fp->ftp_ccount != 0 ||
+				    fp->ftp_mcount != 0) {
 					mutex_exit(&fp->ftp_mtx);
 					fp->ftp_marked = 0;
 					continue;
@@ -447,9 +448,6 @@
 	/*
 	 * We clean up the pid provider for this process here; user-land
 	 * static probes are handled by the meta-provider remove entry point.
-	 * Note that the consumer count is not artificially elevated on the
-	 * pid provider as it is on USDT providers so there's no need to drop
-	 * it here.
 	 */
 	fasttrap_provider_retire(p->p_pid, FASTTRAP_PID_NAME, 0);
 
@@ -902,14 +900,38 @@
 	mutex_exit(&probe->ftp_prov->ftp_mtx);
 
 	/*
-	 * Bail out if we can't find the process for this probe or its
-	 * provider is retired (meaning it was valid in a previously exec'ed
-	 * incarnation of this address space). The provider can't go away
-	 * while we're in this code path.
+	 * If this probe's provider is retired (meaning it was valid in a
+	 * previously exec'ed incarnation of this address space), bail out. The
+	 * provider can't go away while we're in this code path.
+	 */
+	if (probe->ftp_prov->ftp_retired)
+		return;
+
+	/*
+	 * If we can't find the process, it may be that we're in the context of
+	 * a fork in which the traced process is being born and we're copying
+	 * USDT probes. Otherwise, the process is gone so bail.
 	 */
-	if (probe->ftp_prov->ftp_retired ||
-	    (p = sprlock(probe->ftp_pid)) == NULL)
-		return;
+	if ((p = sprlock(probe->ftp_pid)) == NULL) {
+		if ((curproc->p_flag & SFORKING) == 0)
+			return;
+
+		mutex_enter(&pidlock);
+		p = prfind(probe->ftp_pid);
+
+		/*
+		 * Confirm that curproc is indeed forking the process in which
+		 * we're trying to enable probes.
+		 */
+		ASSERT(p != NULL);
+		ASSERT(p->p_parent == curproc);
+		ASSERT(p->p_stat == SIDL);
+
+		mutex_enter(&p->p_lock);
+		mutex_exit(&pidlock);
+
+		sprlock_proc(p);
+	}
 
 	ASSERT(!(p->p_flag & SVFORK));
 	mutex_exit(&p->p_lock);
@@ -1122,8 +1144,7 @@
 	ASSERT(fasttrap_total >= probe->ftp_ntps);
 
 	atomic_add_32(&fasttrap_total, -probe->ftp_ntps);
-	size = sizeof (fasttrap_probe_t) +
-	    sizeof (probe->ftp_tps[0]) * (probe->ftp_ntps - 1);
+	size = offsetof(fasttrap_probe_t, ftp_tps[probe->ftp_ntps]);
 
 	if (probe->ftp_gen + 1 >= fasttrap_mod_gen)
 		fasttrap_mod_barrier(probe->ftp_gen);
@@ -1424,11 +1445,12 @@
 	proc_t *p;
 
 	/*
-	 * There need to be no consumers using this provider and no
-	 * associated enabled probes.
+	 * There need to be no associated enabled probes, no consumers
+	 * creating probes, and no meta providers referencing this provider.
 	 */
+	ASSERT(provider->ftp_rcount == 0);
 	ASSERT(provider->ftp_ccount == 0);
-	ASSERT(provider->ftp_rcount == 0);
+	ASSERT(provider->ftp_mcount == 0);
 
 	fasttrap_proc_release(provider->ftp_proc);
 
@@ -1455,14 +1477,13 @@
 }
 
 static void
-fasttrap_provider_retire(pid_t pid, const char *name, int ccount)
+fasttrap_provider_retire(pid_t pid, const char *name, int mprov)
 {
 	fasttrap_provider_t *fp;
 	fasttrap_bucket_t *bucket;
 	dtrace_provider_id_t provid;
 
 	ASSERT(strlen(name) < sizeof (fp->ftp_name));
-	ASSERT(ccount == 0 || ccount == 1);
 
 	bucket = &fasttrap_provs.fth_table[FASTTRAP_PROVS_INDEX(pid, name)];
 	mutex_enter(&bucket->ftb_mtx);
@@ -1478,6 +1499,14 @@
 		return;
 	}
 
+	mutex_enter(&fp->ftp_mtx);
+	ASSERT(!mprov || fp->ftp_mcount > 0);
+	if (mprov && --fp->ftp_mcount != 0)  {
+		mutex_exit(&fp->ftp_mtx);
+		mutex_exit(&bucket->ftb_mtx);
+		return;
+	}
+
 	/*
 	 * Mark the provider to be removed in our post-processing step,
 	 * mark it retired, and mark its proc as defunct (though it may
@@ -1486,7 +1515,6 @@
 	 * setting the retired flag indicates that we're done with this
 	 * provider; setting the proc to be defunct indicates that all
 	 * tracepoints associated with the traced process should be ignored.
-	 * We also drop the consumer count here by the amount specified.
 	 *
 	 * We obviously need to take the bucket lock before the provider lock
 	 * to perform the lookup, but we need to drop the provider lock
@@ -1495,11 +1523,9 @@
 	 * bucket lock therefore protects the integrity of the provider hash
 	 * table.
 	 */
-	mutex_enter(&fp->ftp_mtx);
 	fp->ftp_proc->ftpc_defunct = 1;
 	fp->ftp_retired = 1;
 	fp->ftp_marked = 1;
-	fp->ftp_ccount -= ccount;
 	provid = fp->ftp_provid;
 	mutex_exit(&fp->ftp_mtx);
 
@@ -1522,7 +1548,6 @@
 	fasttrap_probe_t *pp;
 	fasttrap_tracepoint_t *tp;
 	char *name;
-	size_t size;
 	int i, aframes, whack;
 
 	switch (pdata->ftps_type) {
@@ -1565,10 +1590,8 @@
 		}
 
 		ASSERT(pdata->ftps_noffs > 0);
-		size = sizeof (fasttrap_probe_t) +
-		    sizeof (pp->ftp_tps[0]) * (pdata->ftps_noffs - 1);
-
-		pp = kmem_zalloc(size, KM_SLEEP);
+		pp = kmem_zalloc(offsetof(fasttrap_probe_t,
+		    ftp_tps[pdata->ftps_noffs]), KM_SLEEP);
 
 		pp->ftp_prov = provider;
 		pp->ftp_faddr = pdata->ftps_pc;
@@ -1719,11 +1742,10 @@
 	}
 
 	/*
-	 * We elevate the consumer count here to ensure that this provider
-	 * isn't removed until after the meta provider has been told to
-	 * remove it.
+	 * Up the meta provider count so this provider isn't removed until
+	 * the meta provider has been told to remove it.
 	 */
-	provider->ftp_ccount++;
+	provider->ftp_mcount++;
 
 	mutex_exit(&provider->ftp_mtx);
 
@@ -1738,7 +1760,6 @@
 	fasttrap_provider_t *provider = parg;
 	fasttrap_probe_t *pp;
 	fasttrap_tracepoint_t *tp;
-	size_t size;
 	int i, j;
 	uint32_t ntps;
 
@@ -1751,6 +1772,7 @@
 	}
 
 	ntps = dhpb->dthpb_noffs + dhpb->dthpb_nenoffs;
+	ASSERT(ntps > 0);
 
 	atomic_add_32(&fasttrap_total, ntps);
 
@@ -1760,9 +1782,7 @@
 		return;
 	}
 
-	ASSERT(dhpb->dthpb_noffs > 0);
-	size = sizeof (fasttrap_probe_t) + sizeof (pp->ftp_tps[0]) * (ntps - 1);
-	pp = kmem_zalloc(size, KM_SLEEP);
+	pp = kmem_zalloc(offsetof(fasttrap_probe_t, ftp_tps[ntps]), KM_SLEEP);
 
 	pp->ftp_prov = provider;
 	pp->ftp_pid = provider->ftp_pid;
--- a/usr/src/uts/common/exec/elf/elf.c	Mon Apr 24 19:31:54 2006 -0700
+++ b/usr/src/uts/common/exec/elf/elf.c	Mon Apr 24 21:11:42 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,6 +18,7 @@
  *
  * CDDL HEADER END
  */
+
 /*
  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
@@ -1193,7 +1193,7 @@
  */
 static int
 process_scns(core_content_t content, proc_t *p, cred_t *credp, vnode_t *vp,
-    Shdr *v, int nshdrs, rlim64_t rlimit, Off *doffsetp, int *nshdrsp)
+    Shdr *v, int nv, rlim64_t rlimit, Off *doffsetp, int *nshdrsp)
 {
 	vnode_t *lastvp = NULL;
 	struct seg *seg;
@@ -1284,7 +1284,7 @@
 					    shdr->sh_link * ehdr.e_shentsize);
 				}
 
-				if (v != NULL && i < nshdrs - 1) {
+				if (v != NULL && i < nv - 1) {
 					if (shdr->sh_size > datasz &&
 					    shdr->sh_size <= elf_datasz_max) {
 						if (data != NULL)
@@ -1352,7 +1352,7 @@
 				if (strtab->sh_type != SHT_STRTAB)
 					continue;
 
-				if (v != NULL && i < nshdrs - 2) {
+				if (v != NULL && i < nv - 2) {
 					sz = MAX(symtab->sh_size,
 					    strtab->sh_size);
 					if (sz > datasz &&
@@ -1436,7 +1436,7 @@
 		goto done;
 	}
 
-	if (i != nshdrs - 1) {
+	if (i != nv - 1) {
 		cmn_err(CE_WARN, "elfcore: core dump failed for "
 		    "process %d; address space is changing", p->p_pid);
 		error = EIO;
--- a/usr/src/uts/common/os/dtrace_subr.c	Mon Apr 24 19:31:54 2006 -0700
+++ b/usr/src/uts/common/os/dtrace_subr.c	Mon Apr 24 21:11:42 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -319,19 +319,9 @@
 void
 dtrace_fasttrap_fork(proc_t *p, proc_t *cp)
 {
-	ASSERT(MUTEX_HELD(&p->p_lock));
 	ASSERT(p->p_proc_flag & P_PR_LOCK);
-	mutex_exit(&p->p_lock);
+	ASSERT(p->p_dtrace_count > 0);
+	ASSERT(dtrace_fasttrap_fork_ptr != NULL);
 
-	/*
-	 * If any tracepoints exist, call into the fasttrap module to remove
-	 * those tracepoints. We can rely on that module being loaded since
-	 * the extant tracepoints can't be removed while we hold P_PR_LOCK.
-	 */
-	if (p->p_dtrace_count > 0) {
-		ASSERT(dtrace_fasttrap_fork_ptr != NULL);
-		dtrace_fasttrap_fork_ptr(p, cp);
-	}
-
-	mutex_enter(&p->p_lock);
+	dtrace_fasttrap_fork_ptr(p, cp);
 }
--- a/usr/src/uts/common/os/fork.c	Mon Apr 24 19:31:54 2006 -0700
+++ b/usr/src/uts/common/os/fork.c	Mon Apr 24 21:11:42 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -232,6 +231,7 @@
 		 */
 		mutex_enter(&p->p_lock);
 		sprlock_proc(p);
+		p->p_flag |= SFORKING;
 		mutex_exit(&p->p_lock);
 
 		error = as_dup(p->p_as, &cp->p_as);
@@ -258,6 +258,7 @@
 			task_rele(tk);
 
 			mutex_enter(&p->p_lock);
+			p->p_flag &= ~SFORKING;
 			pool_barrier_exit();
 			continuelwps(p);
 			sprunlock(p);
@@ -272,17 +273,26 @@
 		if (p->p_segacct)
 			shmfork(p, cp);
 
+		/*
+		 * Remove all DTrace tracepoints from the child process. We
+		 * need to do this _before_ duplicating USDT providers since
+		 * any associated probes may be immediately enabled.
+		 */
+		if (p->p_dtrace_count > 0)
+			dtrace_fasttrap_fork(p, cp);
+
+		/*
+		 * Duplicate any helper actions and providers. The SFORKING
+		 * we set above informs the code to enable USDT probes that
+		 * sprlock() may fail because the child is being forked.
+		 */
 		if (p->p_dtrace_helpers != NULL) {
 			ASSERT(dtrace_helpers_fork != NULL);
 			(*dtrace_helpers_fork)(p, cp);
 		}
 
-		/*
-		 * Remove all DTrace tracepoints from the child process.
-		 */
 		mutex_enter(&p->p_lock);
-		if (p->p_dtrace_count > 0)
-			dtrace_fasttrap_fork(p, cp);
+		p->p_flag &= ~SFORKING;
 		sprunlock(p);
 	}
 
--- a/usr/src/uts/common/sys/fasttrap_impl.h	Mon Apr 24 19:31:54 2006 -0700
+++ b/usr/src/uts/common/sys/fasttrap_impl.h	Mon Apr 24 21:11:42 2006 -0700
@@ -85,6 +85,7 @@
 	kmutex_t ftp_mtx;			/* provider lock */
 	uint64_t ftp_rcount;			/* enabled probes ref count */
 	uint64_t ftp_ccount;			/* consumers creating probes */
+	uint64_t ftp_mcount;			/* meta provider count */
 	fasttrap_proc_t *ftp_proc;		/* shared proc for all provs */
 	struct fasttrap_provider *ftp_next;	/* next prov in hash chain */
 } fasttrap_provider_t;
--- a/usr/src/uts/common/sys/proc.h	Mon Apr 24 19:31:54 2006 -0700
+++ b/usr/src/uts/common/sys/proc.h	Mon Apr 24 21:11:42 2006 -0700
@@ -446,6 +446,7 @@
 #define	SSYS	   0x00000001	/* system (resident) process */
 #define	SEXITING   0x00000002	/* process is exiting */
 #define	SITBUSY	   0x00000004	/* setitimer(ITIMER_REAL) in progress */
+#define	SFORKING   0x00000008	/* tells called functions that we're forking */
 #define	SWATCHOK   0x00000010	/* proc in acceptable state for watchpoints */
 #define	SKILLED    0x00000100	/* SIGKILL has been posted to the process */
 #define	SSCONT	   0x00000200	/* SIGCONT has been posted to the process */
--- a/usr/src/uts/intel/dtrace/dtrace_isa.c	Mon Apr 24 19:31:54 2006 -0700
+++ b/usr/src/uts/intel/dtrace/dtrace_isa.c	Mon Apr 24 21:11:42 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -139,7 +139,7 @@
 		s2 = s1 + sizeof (siginfo32_t);
 	}
 
-	while (pc != 0 && sp != 0) {
+	while (pc != 0) {
 		ret++;
 		if (pcstack != NULL) {
 			*pcstack++ = (uint64_t)pc;
@@ -148,6 +148,9 @@
 				break;
 		}
 
+		if (sp == 0)
+			break;
+
 		if (oldcontext == sp + s1 || oldcontext == sp + s2) {
 			if (p->p_model == DATAMODEL_NATIVE) {
 				ucontext_t *ucp = (ucontext_t *)oldcontext;
@@ -336,13 +339,16 @@
 			pc = dtrace_fuword32((void *)rp->r_sp);
 	}
 
-	while (pc != 0 && sp != 0) {
+	while (pc != 0) {
 		*pcstack++ = (uint64_t)pc;
 		*fpstack++ = sp;
 		pcstack_limit--;
 		if (pcstack_limit <= 0)
 			break;
 
+		if (sp == 0)
+			break;
+
 		if (oldcontext == sp + s1 || oldcontext == sp + s2) {
 			if (p->p_model == DATAMODEL_NATIVE) {
 				ucontext_t *ucp = (ucontext_t *)oldcontext;