[DTrace-devel] [PATCH 21/26] usdt: DTrace userspace side
Nick Alcock
nick.alcock at oracle.com
Mon Oct 24 11:00:12 UTC 2022
On 21 Oct 2022, Kris Van Hees via DTrace-devel stated:
> This is implemented almost entirely in the pid provider, which is
> reassuringly similar to how it was done in the in-kernel days. They're
> really very closely-related beasts, and the same code can handle both
> easily enough.
OK so this commit message is not true any more :) do you want to fix it
or shall I?
> - adjusts provide_pid so it can be called at USDT uprobe discovery time
> to create underlying probes that user-requested USDT probes will then
> utilize. The changes here look rather extreme but are actually quite
> small: the underlying probe stuff is split into a new function,
> provide_pid_underlying(), and provide_pid can be asked to do nothingg
> but call this; the probe name follows the new dtprobed rules, looking
> like pid:$inum::$offset, and thus is identical for probes created for
> USDT and for pids at the same offset.
>
> The struct pid_probe attached to the underlying probe gains a device
> number (which it should always have had) and keeps track of the
> underlying uprobe name from create_uprobe or USDT probe discovery
> and remembers whether or not DTrace created it (if dtprobed created
> it, dtrace must not delete it).
>
> provide_pid itself is adjusted to call provide_pid_underlying as
> needed, but also to do more work if the probe already exists: USDT
> 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, and also keep track of all the
> underlying probes associated with an overlying probe so we can enable
> them all (see next item).
This bit, in particular, is not exactly true any more: the same things
are done but in a much easier-to-understand way.
> - stack arg handling needs a bit of a tweak. usdt probes (but not any
> other sorts of probes) are placed after the setup of args for a
> function call but obviously before the actual call, since the
> "function" doesn't exist. On platforms on which
> PT_REGS_ARGSTKBASE > 0, we have to remember to *not* apply the
> ARGSTKBASE adjustment when a usdt probe is being called, since
> that applies to the actual function call, which hasn't happened.
> (In theory, pid offset probes might need this, but figuring out when
> this would be needed would be tricky: we'd need to do it only when
> the probe was placed at the actual site of a function call -- and
> even that would leave us in trouble if the probe was placed in the
> middle of arg setup!)
(and this should mention PP_IS_FUNCALL.)
> Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
FWIW, for the bits I wrote and you rewrote,
Reviewed-by: Nick Alcock <nick.alcock at oracle.com>
-- even if they don't pass their tests this is so much easier to
understand than what I did. I had the division of labour between
provide_pid and provide_pid_underlying all wrong...
> + /* FIXME: DTPPT_IS_ENABLED needs to be supported also. */
> + psp.pps_type = DTPPT_OFFSETS;
Indeed. Not in this phase though :)
> + /*
> + * Does this match the overlying probe we are meant to be
> + * creating? If so, create an overlying probe and let
> + * provide_probe() create the underlying probe for us. Among
> + * other things, this ensures that the PID part of the provider
> + * name gets stuck into the overlying probe properly.
> + *
> + * TODO: wildcard probes get handled here.
> + */
... this, less useful though it is, is quite likely to happen first
(because the stuff it needs is a prerequisite for is-enabled probes
too).
> diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
> new file mode 100644
[...]
> +/*
> + * 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
> + * underlying probe, we may already have one in the system.
> + *
> + * If not found, we create a new probe.
> + */
> +static dt_probe_t *create_underlying(dtrace_hdl_t *dtp,
> + const pid_probespec_t *psp)
> +{
[...]
> +static int provide_probe(dtrace_hdl_t *dtp, const pid_probespec_t *psp,
> + const char *prb, const dt_provimpl_t *pvops, int flags)
> +{
> + char prv[DTRACE_PROVNAMELEN];
> + dt_provider_t *pvp;
> + dtrace_probedesc_t pd;
> + dt_uprobe_t *upp;
> + dt_probe_t *prp, *uprp;
> + list_probe_t *pop, *pup;
[...]
This is so much nicer than what I did... ack ack ack.
--
NULL && (void)
More information about the DTrace-devel
mailing list