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

Kris Van Hees kris.van.hees at oracle.com
Wed Sep 28 12:00:43 UTC 2022


Another important issue...

You are not at all associating the USDT probes with their proper provider
names.  You can see this in the uprobe_events output but also clearly when
tracing.  I modified the usdt/tst.args.d script to probe USDT probes with
provider name test_provFAIL$1 and the script still PASSes even though the
USDT probes in the trigger executable belong to provider test_prov!!

That is a fundamental flaw because it means probe matching ignores the
provider name, which is an essential component of the fully qualified probe
name.

I'll keep working through the review beyond this issue.. Can you resolve this
and post a v4 in the meantime (hopefully incorporating the other review
comments thus far as well)?

	Kris

On Thu, Sep 15, 2022 at 11:54:26AM -0400, Kris Van Hees via DTrace-devel wrote:
> 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
> 
> _______________________________________________
> 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