[DTrace-devel] [PATCH v3] USDT, phase 1

Kris Van Hees kris.van.hees at oracle.com
Thu Sep 15 15:54:26 UTC 2022


One overarching problem: when testing with Debian unstable I see the issue that
various trigger executables with USDT probes cannot be linked.

Debian unstable has: GNU ld (GNU Binutils for Debian) 2.38.90.20220713

The error is:

LINK: usdt-tst-argmap
/usr/bin/ld: /scratch/dtrace-bpf-user/build/test-triggers--usdt-tst-argmap.o: relocation R_X86_64_NONE against absolute symbol `__dtrace_test_prov___place' in section `.text.startup' is disallowed
collect2: error: ld returned 1 exit status

So, I anticipate that there will be issues once systems start moving to a newer
binutils.  We should be ahead of the curve and see why this problem occurs and
either do something to avoid it or (if warranted) submit a patch to fix
binutils.

On Thu, Sep 08, 2022 at 01:26:29PM +0100, Nick Alcock via DTrace-devel wrote:
> This reroll fixes usdt probes with multiple loci
> (test/unittest/usdt/tst.multiple.sh), pid probes with multiple clauses
> (test/unittest/pid/tst.{arg*,ret*}.d), and return pid probes that share a
> locus with entry probes (test/unittest/pid/tst.float.d and others).
> 
> We do *not* remove the somewhat strange thing where we add even probes with
> no trampoline to the enabled list, because as far as I can see we have to
> add them because it's only by virtue of (overlying) probes with no
> trampoline getting enabled that the underlying probes get enabled at all!
> So if we don't enable them, nothing is ever enabled and nothing works.  No
> code is generated for trampolineless probes, so everything *looks* fine to
> me. You're welcome to find another way, of course :)
> 
> All pid and usdt tests passing except usdt/tst.entryreturn.sh, which has
> some as-yet-undiagnosed problem. Full tests still running (the syscall
> provider triggering kernel crashes is not helping, but is likely unrelated).
> 
> Patches 12 and 16 have actually changed: patch 20 is merely context.
> 
> Full range diff from last set of postings:
> 
>  1:  8638d1fada45 =  1:  8638d1fada45 Revert "Remove drti.o and related support code."
>  2:  51adb978a84e =  2:  51adb978a84e drti: emit into a subdirectory
>  3:  4e049adf837e =  3:  4e049adf837e drti: reference first loaded segment of object containing dtrace_dof_init
>  4:  41e02c5a9778 =  4:  41e02c5a9778 pid: drop dpp_stret
>  5:  04d7f8ac9fd8 =  5:  04d7f8ac9fd8 runtest: make ZAPTHESE an array
>  6:  34631890f964 =  6:  34631890f964 uapi headers: include <sys/dtrace_types> as needed
>  7:  0452527b7b24 =  7:  0452527b7b24 dt_link: finish backing out varint, fixing dt_link-generated object files
>  8:  aaf630166e62 =  8:  aaf630166e62 providers: allow providers with no trampoline
>  9:  996ce3c5429c =  9:  996ce3c5429c port: add daemonization support code
> 10:  096aa7db4af2 = 10:  096aa7db4af2 libproc: add Pinode_to_map()
> 11:  05a389f7bb6c = 11:  05a389f7bb6c libproc: fix double-free on error path
> 12:  ac0d0931b565 ! 12:  f859a10b8556 usdt: daemon
>     @@ dtprobed/uprobes.c (new)
>      +	char *name, *final_name;
>      +
>      +	if (usdt_probe_name == NULL) {
>     -+		if (asprintf(&name, "dt_pid_%llx_%llx_%llx",
>     ++		if (asprintf(&name, "dt_pid_%s%llx_%llx_%llx",
>     ++			     isret ? "ret_" : "",
>      +			     (unsigned long long) dev,
>      +			     (unsigned long long) ino,
>      +			     (unsigned long long) addr) < 0)
>     @@ dtprobed/uprobes.c (new)
>      +		if (!encoded_name)
>      +			return NULL;
>      +
>     -+		if (asprintf(&name, "dt_pid_%llx_%llx_%llx_%s",
>     ++		if (asprintf(&name, "dt_pid_%s%llx_%llx_%llx_%s",
>     ++			     isret ? "ret_" : "",
>      +			     (unsigned long long) dev,
>      +			     (unsigned long long) ino,
>      +			     (unsigned long long) addr, encoded_name) < 0) {
> 13:  a96414cdc455 = 13:  2ec8eaaa947c drti: use /proc/self/maps
> 14:  a1824dc560c8 = 14:  1090c63feec7 fbt, syscall: use getline(), not fgets()
> 15:  da5df66da59e = 15:  91606778a81c dof: don't emit providers with no probes
> 16:  150064f83602 ! 16:  b8a00c7ada78 usdt: DTrace userspace side
>     @@ Commit message
>             probes can be associated with more than one underlying probe (if the
>             probe appears repeatedly in a program), so if it is repeatedly
>             provide_pid'ed with different offsets, we spot this and chain it into
>     -       all the necessary underlying probes.  (This means a bit of flailing
>     -       about, since we suddenly need a new tiny structure whose sole purpose
>     -       is to be in this list and point at the real probe.)
>     +       all the necessary underlying probes, and also keep track of all the
>     +       underlying probes associated with an overlying probe so we can enable
>     +       them all (see next item).
>      
>           - enabling gets a little more complex.  We can no longer get away with
>             just enabling the underlying probe, because things not in the
>             enablings list don't get entries in the probename strtab, and their
>     -       probename is liable to be empty.  So we intern both the overlying
>     -       *and* the underlying probe, and arrange for the overlying probe to
>     -       have no trampoline: in conjunction with a prior commit in this series
>     -       this causes only the underlying probe to have any BPF code generated
>     -       for it.
>     +       probename is liable to be empty: in any case, the underlying probes
>     +       aren't going to get ->enable called for them because the user never
>     +       named them (only their overlying probe).  So we intern both the
>     +       overlying *and* the underlying probe in enablings (by getting
>     +       ->enable for the overlying probe to walk its list of underlying
>     +       probes and enable all of them), and arrange for the overlying probe
>     +       to have no trampoline: in conjunction with a prior commit in this
>     +       series this causes only the underlying probe to have any BPF code
>     +       generated for it.
>      
>           - Trampoline generation has to adapt to this, but also has to use a
>             less kludgy way of figuring out the pids the trampoline applies to:
>     @@ libdtrace/dt_pid.c: dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl
>      +		 */
>      +		if (dpr && dpr->dpr_proc) {
>      +			assert(MUTEX_HELD(&dpr->dpr_lock));
>     -+			if (Pinode_to_map(dpr->dpr_proc, dev, inum) == NULL) {
>     -+				dt_dprintf("inode -> map for %i %lx:%lx failed\n", dpr->dpr_pid, dev, inum);
>     ++			if (Pinode_to_map(dpr->dpr_proc, dev, inum) == NULL)
>      +				goto next;
>     -+			}
>      +		}
>      +
>      +		/*
>     @@ libdtrace/dt_pid.c: dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl
>      +		if (pvp->impl->provide_pid(dtp, &psp) < 0 && pdp) {
>      +			dt_pid_error(dtp, pcb, dpr, D_PROC_USDT,
>      +				     "failed to instantiate probe %s for pid %d: %s",
>     -+				     pdp->prb, dpr->dpr_pid, strerror(errno));
>     ++				     pdp->prb, dpr->dpr_pid,
>     ++				     dtrace_errmsg(dtp, dtrace_errno(dtp)));
>      +			ret = -1;
>      +		}
>      +
>     @@ libdtrace/dt_prov_pid.c
>       	dt_list_t	probes;
>      +	char		*uprobe_name;
>      +	int		dtrace_created;
>     ++	int		is_return;
>       } pid_probe_t;
>       
>     -+typedef struct pid_overlying_probe {
>     ++typedef struct pid_probe_list {
>      +	dt_list_t	list;			/* forward/back pointers */
>      +	dt_probe_t	*probe;			/* the probe in question */
>     -+} pid_overlying_probe_t;
>     ++} pid_probe_list_t;
>      +
>       static const dtrace_pattr_t	pattr = {
>       { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA },
>     @@ libdtrace/dt_prov_pid.c: dt_provimpl_t	dt_pid_proc;
>       	return 0;
>       }
>       
>     - static void probe_destroy(dtrace_hdl_t *dtp, void *datap)
>     +-static void probe_destroy(dtrace_hdl_t *dtp, void *datap)
>     ++/*
>     ++ * Destroy an underlying probe.
>     ++ */
>     ++
>     ++static void probe_udestroy(dtrace_hdl_t *dtp, void *datap)
>       {
>      -	pid_probe_t	*pp = datap;
>      -	tp_probe_t	*tpp = pp->tp;
>      +	pid_probe_t		*pp = datap;
>      +	tp_probe_t		*tpp = pp->tp;
>     -+	pid_overlying_probe_t	*pop, *pop_next;
>     ++	pid_probe_list_t	*pop, *pop_next;
>       
>       	dt_tp_destroy(dtp, tpp);
>       	dt_free(dtp, pp->fn);
>     @@ libdtrace/dt_prov_pid.c: dt_provimpl_t	dt_pid_proc;
>       	dt_free(dtp, pp);
>       }
>       
>     ++/*
>     ++ * Destroy an overlying probe.
>     ++ */
>     ++static void probe_destroy(dtrace_hdl_t *dtp, void *datap)
>     ++{
>     ++	pid_probe_list_t	*pup = datap, *pup_next;
>     ++
>     ++	for (pup = datap; pup != NULL; pup = pup_next) {
>     ++		pup_next = dt_list_next(pup);
>     ++		dt_free(dtp, pup);
>     ++	}
>     ++}
>     ++
>     ++
>      +/*
>      + * Look up or create an underlying (real) probe, corresponding directly to a
>      + * uprobe.  Since multiple pid and USDT probes may all map onto the same
>     @@ libdtrace/dt_prov_pid.c: dt_provimpl_t	dt_pid_proc;
>      +
>      +	/*
>      +	 * The module for these probes is the mapping inode number, in hex
>     -+	 * (filled in by the caller): the function is unset, and the probe name
>     -+	 * is the offset.  (This is amenable to change if it turns out to be
>     -+	 * inconvenient: but it's more or less arbitrary anyway.  It just needs
>     -+	 * to be something that is determinable both for pid and USDT probes.)
>     ++	 * (filled in by the caller): the function is "underlying", and the
>     ++	 * probe name is the offset.  (This is amenable to change if it turns
>     ++	 * out to be inconvenient: but it's more or less arbitrary anyway.  It
>     ++	 * just needs to be something that is determinable both for pid and USDT
>     ++	 * probes.)
>     ++	 *
>     ++	 * Return probes get more info from the overlying probe, since they are
>     ++	 * in a different namespace to other uprobes and don't need to worry
>     ++	 * about colocation with usdt probes.
>      +	 *
>      +	 * XXX does this mean we lump together all probes with a given offset
>      +	 * when doing wildcarding?  This is hardly ideal.  Do we want underlying
>     @@ libdtrace/dt_prov_pid.c: dt_provimpl_t	dt_pid_proc;
>      +	pd.id = DTRACE_IDNONE;
>      +	pd.prv = prvname;
>      +	pd.mod = psp->pps_mod;
>     -+	pd.fun = "";
>      +	pd.prb = psp->pps_prb;
>     ++
>     ++	if (psp && overlying && overlying->pps_type == DTPPT_RETURN)
>     ++		pd.fun = psp->pps_fun;
>     ++	else
>     ++		pd.fun = "underlying";
>     ++
>      +	prp = dt_probe_lookup(dtp, &pd);
>      +	if (prp == NULL) {
>      +		dt_provider_t *pvp;
>     @@ libdtrace/dt_prov_pid.c: dt_provimpl_t	dt_pid_proc;
>      +		if (psp->pps_uprobe_name) {
>      +			pp->uprobe_name = strdup(psp->pps_uprobe_name);
>      +			if (pp->uprobe_name == NULL)
>     -+				goto fail;
>     ++				goto fail_errno;
>      +		}
>      +
>      +		pp->dev = psp->pps_dev;
>     @@ libdtrace/dt_prov_pid.c: dt_provimpl_t	dt_pid_proc;
>      +		if (pp->tp == NULL)
>      +			goto fail;
>      +
>     -+		prp = dt_probe_insert(dtp, pvp, prvname, pd.mod, pp->fn,
>     -+				      pd.prb, pp);
>     ++		prp = dt_probe_insert(dtp, pvp, pd.prv, pd.mod, pd.fun, pd.prb,
>     ++				      pp);
>      +		if (prp == NULL)
>      +			goto fail;
>     ++
>     ++		if (overlying && overlying->pps_type == DTPPT_RETURN)
>     ++			pp->is_return = 1;
>      +	}
>     ++	else
>     ++		pp = prp->prv_data;
>      +
>      +	return prp;
>     ++fail_errno:
>     ++	dt_set_errno(dtp, errno);
>      +fail:
>      +	probe_destroy(dtp, pp);
>      +	free(pp->uprobe_name);
>     @@ libdtrace/dt_prov_pid.c: dt_provimpl_t	dt_pid_proc;
>       static int provide_pid(dtrace_hdl_t *dtp, const pid_probespec_t *psp)
>       {
>       	char			prv[DTRACE_PROVNAMELEN];
>     - 	char			mod[DTRACE_MODNAMELEN];
>     - 	char			prb[DTRACE_NAMELEN];
>     +-	char			mod[DTRACE_MODNAMELEN];
>     +-	char			prb[DTRACE_NAMELEN];
>      -	dt_provider_t		*pidpvp;
>     ++	const char		*mod;
>     ++	const char		*prb;
>     ++	char			underlying_mod[DTRACE_MODNAMELEN];
>      +	char			underlying_prb[DTRACE_NAMELEN];
>       	dt_provider_t		*pvp;
>       	dtrace_probedesc_t	pd;
>     @@ libdtrace/dt_prov_pid.c: dt_provimpl_t	dt_pid_proc;
>      +	dt_probe_t		*prp, *uprp;
>      +	uint64_t		off = psp->pps_addr;
>      +	pid_probespec_t		pp_psp;
>     -+	pid_overlying_probe_t	*pop;
>     ++	pid_probe_list_t	*pop, *pup;
>      +
>      +	if (psp->pps_type == DTPPT_UNDERLYING) {
>      +		if (provide_pid_underlying(dtp, psp))
>     @@ libdtrace/dt_prov_pid.c: dt_provimpl_t	dt_pid_proc;
>       
>      +	snprintf(underlying_prb, sizeof(underlying_prb), "%lx", off);
>      +
>     -+	strcpy(mod, psp->pps_mod);
>     ++	mod = psp->pps_mod;
>       	switch (psp->pps_type) {
>       	case DTPPT_ENTRY:
>     - 		strncpy(prb, "entry", sizeof(prb));
>     -@@ libdtrace/dt_prov_pid.c: static int provide_pid(dtrace_hdl_t *dtp, const pid_probespec_t *psp)
>     - 		strncpy(prb, "return", sizeof(prb));
>     +-		strncpy(prb, "entry", sizeof(prb));
>     ++		prb = "entry";
>     + 		break;
>     + 	case DTPPT_RETURN:
>     +-		strncpy(prb, "return", sizeof(prb));
>     ++		prb = "return";
>     ++		/*
>     ++		 * Return probes are in their own namespace and cannot collide
>     ++		 * with other probes: so we can give them a name that reflects
>     ++		 * their nature, since their nature is known (while other
>     ++		 * underlying probes might serve both USDT and pid probes at the
>     ++		 * same time, or pid and glob-offset, etc).
>     ++		 */
>     ++		sprintf(underlying_prb, "return");
>       		break;
>       	case DTPPT_OFFSETS:
>      -		snprintf(prb, sizeof(prb), "%lx", off);
>     -+		strcpy(prb, underlying_prb);
>     ++		prb = underlying_prb;
>      +		break;
>      +	case DTPPT_USDT:
>     -+		strcpy(prb, psp->pps_usdt_prb);
>     -+		strcpy(mod, psp->pps_usdt_mod);
>     ++		prb = psp->pps_usdt_prb;
>     ++		mod = psp->pps_usdt_mod;
>       		break;
>       	default:
>      -		return 0;
>     @@ libdtrace/dt_prov_pid.c: static int provide_pid(dtrace_hdl_t *dtp, const pid_pro
>      -	 * "return", or the offset into the function (in hex).
>      -	 */
>      -	snprintf(mod, sizeof(mod), "%lx", psp->pps_ino);
>     -+	snprintf(mod, sizeof(mod), "%lx", psp->pps_inum);
>     ++	snprintf(underlying_mod, sizeof(underlying_mod), "%lx", psp->pps_inum);
>      +
>      +	/* Get (or create) the underlying probe.  */
>      +	memcpy(&pp_psp, psp, sizeof(pid_probespec_t));
>      +	pp_psp.pps_type = DTPPT_UNDERLYING;
>     -+	pp_psp.pps_mod = mod;
>     ++	pp_psp.pps_mod = underlying_mod;
>      +	pp_psp.pps_prb = underlying_prb;
>      +	uprp = provide_pid_underlying(dtp, &pp_psp);
>      +
>     @@ libdtrace/dt_prov_pid.c: static int provide_pid(dtrace_hdl_t *dtp, const pid_pro
>      -		pp->tp = dt_tp_alloc(dtp);
>      -		if (pp->tp == NULL)
>      -			goto fail;
>     -+	pop = dt_zalloc(dtp, sizeof(pid_overlying_probe_t));
>     ++	/*
>     ++	 * Underlying and overlying probe list entries.
>     ++	 */
>     ++	pop = dt_zalloc(dtp, sizeof(pid_probe_list_t));
>      +	if (pop == NULL)
>      +		return -1;
>     ++
>     ++	pup = dt_zalloc(dtp, sizeof(pid_probe_list_t));
>     ++	if (pup == NULL) {
>     ++		dt_free(dtp, pop);
>     ++		return -1;
>     ++	}
>       
>      -		prp = dt_probe_insert(dtp, pidpvp, prvname, mod, psp->pps_fun,
>      -				      prb, pp);
>     @@ libdtrace/dt_prov_pid.c: static int provide_pid(dtrace_hdl_t *dtp, const pid_pro
>      -	/* Try to add the pid probe. */
>      -	prp = dt_probe_insert(dtp, pvp, prv, psp->pps_mod, psp->pps_fun, prb,
>      -			      prp);
>     --	if (prp == NULL)
>     ++	pup->probe = uprp;
>     + 	if (prp == NULL)
>      -		goto fail;
>     -+	if (prp ==  NULL)
>     -+		prp = dt_probe_insert(dtp, pvp, prv, psp->pps_mod, psp->pps_fun,
>     -+		    prb, uprp);
>     ++		prp = dt_probe_insert(dtp, pvp, pd.prv, pd.mod, pd.fun, pd.prb,
>     ++				      pup);
>     ++	else
>     ++		dt_list_append((dt_list_t *) prp->prv_data, pup);
>       
>      -	/* Add the pid probe to the list of probes for the main (real) probe. */
>      -	dt_list_append(&pp->probes, prp);
>      +	if (prp == NULL) {
>      +		dt_free(dtp, pop);
>     ++		dt_free(dtp, pup);
>      +		return -1;
>      +	}
>       
>     @@ libdtrace/dt_prov_pid.c: static int provide_pid(dtrace_hdl_t *dtp, const pid_pro
>       	return 0;
>       }
>       
>     -@@ libdtrace/dt_prov_pid.c: static void enable(dtrace_hdl_t *dtp, dt_probe_t *prp)
>     + static void enable(dtrace_hdl_t *dtp, dt_probe_t *prp)
>       {
>     ++	const pid_probe_list_t *pup;
>       	assert(prp->prov->impl == &dt_pid_proc);
>       
>      -	/* We need to enable the main (real) probe (if not enabled yet). */
>     +-	dt_probe_enable(dtp, (dt_probe_t *)prp->prv_data);
>      +	/*
>     -+	 * We need to enable the main (real) probe (if not enabled yet).
>     ++	 * We need to enable the underlying probes (if not enabled yet).
>      +	 */
>     - 	dt_probe_enable(dtp, (dt_probe_t *)prp->prv_data);
>     -+
>     ++	for (pup = prp->prv_data; pup != NULL; pup = dt_list_next(pup)) {
>     ++		dt_probe_t *uprp = pup->probe;
>     ++		dt_probe_enable(dtp, uprp);
>     ++	}
>      +
>      +	/*
>      +	 * Finally, ensure we're in the list of enablings as well.
>     @@ libdtrace/dt_prov_pid.c: static void enable(dtrace_hdl_t *dtp, dt_probe_t *prp)
>      +	dt_irlist_t			*dlp = &pcb->pcb_ir;
>      +	const dt_probe_t		*prp = pcb->pcb_probe;
>      +	const pid_probe_t		*pp = prp->prv_data;
>     -+	const pid_overlying_probe_t	*pop;
>     ++	const pid_probe_list_t		*pop;
>      +	uint_t				lbl_exit = pcb->pcb_exitlbl;
>       
>       	dt_cg_tramp_prologue(pcb);
>       
>     +@@ libdtrace/dt_prov_pid.c: static void trampoline(dt_pcb_t *pcb)
>     + 	 */
>     + 
>     + 	dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
>     +-	if (strcmp(pcb->pcb_probe->desc->prb, "return") == 0)
>     ++	if (pp->is_return)
>     + 		dt_cg_tramp_copy_rval_from_regs(pcb, BPF_REG_8);
>     + 	else
>     + 		dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
>      @@ libdtrace/dt_prov_pid.c: static void trampoline(dt_pcb_t *pcb)
>       	 * are no assignments to %r0 possible in between the conditional
>       	 * statements.
>     @@ libdtrace/dt_prov_pid.c: static int attach(dtrace_hdl_t *dtp, const dt_probe_t *
>      +				return -ENOENT;
>      +
>      +			prb = uprobe_create(pp->dev, pp->inum, pp->off, spec, NULL,
>     -+			    prp->desc->prb[0] == 'r');
>     ++					    pp->is_return);
>      +			free(spec);
>      +			if (prb == NULL)
>      +				return -ENOENT;
>     @@ libdtrace/dt_prov_pid.c: static void detach(dtrace_hdl_t *dtp, const dt_probe_t
>       	.name		= prvname,
>       	.prog_type	= BPF_PROG_TYPE_KPROBE,
>      @@ libdtrace/dt_prov_pid.c: dt_provimpl_t	dt_pid = {
>     - 	.probe_destroy	= &probe_destroy,
>     + 	.attach		= &attach,
>     + 	.probe_info	= &probe_info,
>     + 	.detach		= &detach,
>     +-	.probe_destroy	= &probe_destroy,
>     ++	.probe_destroy	= &probe_udestroy,
>       };
>       
>      +/*
>     @@ libdtrace/dt_prov_pid.c: dt_provimpl_t	dt_pid = {
>       	.name		= prvname,
>       	.prog_type	= BPF_PROG_TYPE_KPROBE,
>       	.provide_pid	= &provide_pid,
>     --	.enable		= &enable,
>     + 	.enable		= &enable,
>      -	.trampoline	= &trampoline,
>     -+	.enable		= &enable
>     ++	.probe_destroy	= &probe_destroy,
>       };
> 17:  b9c0adc1c3c8 = 17:  15c0acee80b0 usdt: testsuite updates
> 18:  88a895fe7844 = 18:  34606d200a69 test, usdt, pid: remove arg count check
> 19:  e63129c83f3a = 19:  206b038b63b9 test: Signal an error if trigger does not exist
> 20:  5f634879aad5 ! 20:  6758bc71ad66 usdt: fix stack args on PT_REGS_ARGSTKBASE > 0 platforms
>     @@ libdtrace/dt_prov_fbt.c: static void trampoline(dt_pcb_t *pcb)
>      
>       ## libdtrace/dt_prov_pid.c ##
>      @@ libdtrace/dt_prov_pid.c: typedef struct pid_probe {
>     - 	dt_list_t	probes;
>       	char		*uprobe_name;
>       	int		dtrace_created;
>     + 	int		is_return;
>      +	int		arg_setup;
>       } pid_probe_t;
>       
>     - typedef struct pid_overlying_probe {
>     + typedef struct pid_probe_list {
>      @@ libdtrace/dt_prov_pid.c: static void probe_destroy(dtrace_hdl_t *dtp, void *datap)
>        * If not found, we create a new probe.
>        */
>     @@ libdtrace/dt_prov_pid.c: static void probe_destroy(dtrace_hdl_t *dtp, void *data
>       	dtrace_probedesc_t	pd;
>       	dt_probe_t		*prp;
>      @@ libdtrace/dt_prov_pid.c: static dt_probe_t *provide_pid_underlying(dtrace_hdl_t *dtp,
>     - 		if (prp == NULL)
>     - 			goto fail;
>     - 	}
>     -+	else
>     -+		pp = prp->prv_data;
>     -+
>     + 	else
>     + 		pp = prp->prv_data;
>     + 
>      +	/*
>      +	 * USDT probes are positioned after argument setup for a function that
>      +	 * is never actually called, so the stack is slightly different from the
>     @@ libdtrace/dt_prov_pid.c: static dt_probe_t *provide_pid_underlying(dtrace_hdl_t
>      +	 */
>      +	if (overlying && overlying->pps_type == DTPPT_USDT)
>      +		pp->arg_setup = 1;
>     - 
>     ++
>       	return prp;
>     - fail:
>     + fail_errno:
>     + 	dt_set_errno(dtp, errno);
>      @@ libdtrace/dt_prov_pid.c: static int provide_pid(dtrace_hdl_t *dtp, const pid_probespec_t *psp)
>     - 	pid_overlying_probe_t	*pop;
>     + 	pid_probe_list_t	*pop, *pup;
>       
>       	if (psp->pps_type == DTPPT_UNDERLYING) {
>      -		if (provide_pid_underlying(dtp, psp))
>     @@ libdtrace/dt_prov_pid.c: static int provide_pid(dtrace_hdl_t *dtp, const pid_pro
>       			return -1;
>      @@ libdtrace/dt_prov_pid.c: static int provide_pid(dtrace_hdl_t *dtp, const pid_probespec_t *psp)
>       	pp_psp.pps_type = DTPPT_UNDERLYING;
>     - 	pp_psp.pps_mod = mod;
>     + 	pp_psp.pps_mod = underlying_mod;
>       	pp_psp.pps_prb = underlying_prb;
>      -	uprp = provide_pid_underlying(dtp, &pp_psp);
>      +	uprp = provide_pid_underlying(dtp, &pp_psp, psp);
>     @@ libdtrace/dt_prov_pid.c: static int provide_pid(dtrace_hdl_t *dtp, const pid_pro
>       	if (uprp == NULL)
>       		return -1;
>      @@ libdtrace/dt_prov_pid.c: static void trampoline(dt_pcb_t *pcb)
>     - 	if (strcmp(pcb->pcb_probe->desc->prb, "return") == 0)
>     + 	if (pp->is_return)
>       		dt_cg_tramp_copy_rval_from_regs(pcb, BPF_REG_8);
>       	else
>      -		dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
> 
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel



More information about the DTrace-devel mailing list