[DTrace-devel] [PATCH 2/2] rawfbt: prvname is not properly set
Kris Van Hees
kris.van.hees at oracle.com
Fri Jan 16 22:02:09 UTC 2026
On Fri, Jan 16, 2026 at 12:18:51AM -0500, Eugene Loh wrote:
> On 1/15/26 17:18, Kris Van Hees wrote:
>
> > On Tue, Jan 13, 2026 at 04:42:05PM -0500, eugene.loh at oracle.com wrote:
> > > From: Eugene Loh <eugene.loh at oracle.com>
> > >
> > > The char array prvname[] is set for each provider. It is used in the
> > > file that implements the provider. It might also be passed to
> > > dt_sdt_populate() via a function argument.
> > >
> > > However, dt_provider_tp.h also defines the macro GROUP_DATA in terms of
> > > prvname. In turn, GROUP_DATA is used not only in dt_prov_dtrace.c but
> > > then again in dt_prov_fbt.c to define FBT_GROUP_DATA.
> > >
> > > In commit 0b7c5a632 ("fbt, rawfbt: consolidate code to avoid duplication"),
> > > the fbt and rawfbt providers are combined into a single file. Thus, two
> > > uses of prvname collide. The in-file collisions get resolved, but the
> > > cascade of macro definitions does not: FBT_GROUP_DATA ends up using
> > > "fbt" for both fbt and rawfbt providers. As a result, it is possible
> > > for rawfbt probes not to be seen.
> > >
> > > Notice that GROUP_DATA is always paired with prp->desc->prb. Therefore,
> > > simply replace:
> > > -#define GROUP_DATA getpid(), prvname
> > > +#define PROBE_DATA getpid(), prp->desc->prv, prp->desc->prb
> > > This makes the code more compact and relieves the macro definitions from
> > > needing prvname. It also makes the FBT_GROUP_DATA macro unnecessary.
> > >
> > > The format (FMT) macro is similarly renamed and redefined to include the
> > > probe info.
> > >
> > > Add a test to check that a rawfbt probe can be found behind an fbt probe
> > > when the probe description has a wildcard provider.
> > >
> > > Orabug: 38842114
> > > Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
> > > ---
> > > libdtrace/dt_prov_dtrace.c | 14 ++++++-------
> > > libdtrace/dt_prov_fbt.c | 13 ++++++------
> > > libdtrace/dt_prov_rawtp.c | 4 ++--
> > > libdtrace/dt_prov_sdt.c | 4 ++--
> > > libdtrace/dt_provider_tp.h | 12 +++++------
> > > .../providers/rawfbt/tst.wildcard-provider.d | 20 +++++++++++++++++++
> > > .../providers/rawfbt/tst.wildcard-provider.r | 2 ++
> > > 7 files changed, 45 insertions(+), 24 deletions(-)
> > > create mode 100644 test/unittest/providers/rawfbt/tst.wildcard-provider.d
> > > create mode 100644 test/unittest/providers/rawfbt/tst.wildcard-provider.r
> > >
> > > diff --git a/libdtrace/dt_prov_dtrace.c b/libdtrace/dt_prov_dtrace.c
> > > index 34b5d8e24..102afd84e 100644
> > > --- a/libdtrace/dt_prov_dtrace.c
> > > +++ b/libdtrace/dt_prov_dtrace.c
> > > @@ -243,8 +243,8 @@ static int attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
> > > /* add a uprobe */
> > > fd = open(UPROBE_EVENTS, O_WRONLY | O_APPEND);
> > > if (fd != -1) {
> > > - rc = dprintf(fd, "p:" GROUP_FMT "/%s %s\n",
> > > - GROUP_DATA, prp->desc->prb, spec);
> > > + rc = dprintf(fd, "p:" PROBE_FMT " %s\n",
> > > + PROBE_DATA, spec);
> > > close(fd);
> > > }
> > > free(spec);
> > > @@ -252,14 +252,14 @@ static int attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
> > > return -ENOENT;
> > > /* open format file */
> > > - len = snprintf(NULL, 0, "%s" GROUP_FMT "/%s/format",
> > > - EVENTSFS, GROUP_DATA, prp->desc->prb) + 1;
> > > + len = snprintf(NULL, 0, "%s" PROBE_FMT "/format",
> > > + EVENTSFS, PROBE_DATA) + 1;
> > > fn = dt_alloc(dtp, len);
> > > if (fn == NULL)
> > > return -ENOENT;
> > > - snprintf(fn, len, "%s" GROUP_FMT "/%s/format",
> > > - EVENTSFS, GROUP_DATA, prp->desc->prb);
> > > + snprintf(fn, len, "%s" PROBE_FMT "/format",
> > > + EVENTSFS, PROBE_DATA);
> > How about also changing this to use asprintf() rather than doing the douoble
> > snprintf (one to get the langth, the alloc, and then actually populate).
>
> Sure, sounds good. On the other hand, this is in dt_prov_dtrace, while the
> main point of the patch is an fbt problem. Yeah, I know, not a big deal.
> But since we've been chasing these asprintf() sites opportunistically over a
> couple of patches and there are several (4?) more sites to go, how about I
> do all these asprintf() conversions in a separate patch?
Sounds good (and thank you for already posting those).
> > > f = fopen(fn, "r");
> > > dt_free(dtp, fn);
> > > if (f == NULL)
> > > @@ -300,7 +300,7 @@ static void detach(dtrace_hdl_t *dtp, const dt_probe_t *prp)
> > > if (fd == -1)
> > > return;
> > > - dprintf(fd, "-:" GROUP_FMT "/%s\n", GROUP_DATA, prp->desc->prb);
> > > + dprintf(fd, "-:" PROBE_FMT "\n", PROBE_DATA);
> > > close(fd);
> > > }
> > > diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
> > > index 3feac56ea..8dbf9740a 100644
> > > --- a/libdtrace/dt_prov_fbt.c
> > > +++ b/libdtrace/dt_prov_fbt.c
> > > @@ -53,8 +53,7 @@ static const char prvname[] = "fbt";
> > > #define KPROBE_EVENTS TRACEFS "kprobe_events"
> > > -#define FBT_GROUP_FMT GROUP_FMT "_%s"
> > > -#define FBT_GROUP_DATA GROUP_DATA, prp->desc->prb
> > > +#define FBT_PROBE_FMT "dt_%d_%s_%s"
> > > static const dtrace_pattr_t pattr = {
> > > { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
> > > @@ -508,16 +507,16 @@ static int kprobe_attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
> > > if (fd == -1)
> > > goto out;
> > > - rc = dprintf(fd, "%c:" FBT_GROUP_FMT "/%s %s\n",
> > > + rc = dprintf(fd, "%c:" FBT_PROBE_FMT "/%s %s\n",
> > > prp->desc->prb[0] == 'e' ? 'p' : 'r',
> > > - FBT_GROUP_DATA, tpn, fun);
> > > + PROBE_DATA, tpn, fun);
> > > close(fd);
> > > if (rc == -1)
> > > goto out;
> > > /* create format file name */
> > > - if (asprintf(&fn, "%s" FBT_GROUP_FMT "/%s/format", EVENTSFS,
> > > - FBT_GROUP_DATA, tpn) == -1)
> > > + if (asprintf(&fn, "%s" FBT_PROBE_FMT "/%s/format", EVENTSFS,
> > > + PROBE_DATA, tpn) == -1)
> > > goto out;
> > > /* open format file */
> > > @@ -583,7 +582,7 @@ static void kprobe_detach(dtrace_hdl_t *dtp, const dt_probe_t *prp)
> > > }
> > > }
> > > - dprintf(fd, "-:" FBT_GROUP_FMT "/%s\n", FBT_GROUP_DATA, tpn);
> > > + dprintf(fd, "-:" FBT_PROBE_FMT "/%s\n", PROBE_DATA, tpn);
> > > close(fd);
> > > if (tpn != prp->desc->fun)
> > > diff --git a/libdtrace/dt_prov_rawtp.c b/libdtrace/dt_prov_rawtp.c
> > > index 709f7040f..e3269f4b3 100644
> > > --- a/libdtrace/dt_prov_rawtp.c
> > > +++ b/libdtrace/dt_prov_rawtp.c
> > > @@ -56,7 +56,7 @@ static const dtrace_pattr_t pattr = {
> > > /*
> > > * The PROBE_LIST file lists all tracepoints in a <group>:<name> format.
> > > * We need to ignore these groups:
> > > - * - GROUP_FMT (created by DTrace processes)
> > > + * - PROBE_SFMT
> > > * - kprobes and uprobes
> > > * - syscalls (handled by a different provider)
> > > * - pid and usdt probes (ditto)
> > > @@ -89,7 +89,7 @@ static int populate(dtrace_hdl_t *dtp)
> > > *p++ = '\0';
> > > - if (sscanf(buf, GROUP_SFMT, &dummy, &str) == 2) {
> > > + if (sscanf(buf, PROBE_SFMT, &dummy, &str) == 2) {
> > > free(str);
> > > continue;
> > > }
> > > diff --git a/libdtrace/dt_prov_sdt.c b/libdtrace/dt_prov_sdt.c
> > > index 74555f5be..ee2cc3c27 100644
> > > --- a/libdtrace/dt_prov_sdt.c
> > > +++ b/libdtrace/dt_prov_sdt.c
> > > @@ -54,7 +54,7 @@ static const dtrace_pattr_t pattr = {
> > > /*
> > > * The PROBE_LIST file lists all tracepoints in a <group>:<name> format.
> > > * We need to ignore these groups:
> > > - * - GROUP_FMT (created by DTrace processes)
> > > + * - PROBE_SFMT
> > > * - kprobes and uprobes
> > > * - syscalls (handled by a different provider)
> > > * - pid and usdt probes (ditto)
> > > @@ -87,7 +87,7 @@ static int populate(dtrace_hdl_t *dtp)
> > > *p++ = '\0';
> > > - if (sscanf(buf, GROUP_SFMT, &dummy, &str) == 2) {
> > > + if (sscanf(buf, PROBE_SFMT, &dummy, &str) == 2) {
> > > free(str);
> > > continue;
> > > }
> > > diff --git a/libdtrace/dt_provider_tp.h b/libdtrace/dt_provider_tp.h
> > > index f131b1e02..406609d1b 100644
> > > --- a/libdtrace/dt_provider_tp.h
> > > +++ b/libdtrace/dt_provider_tp.h
> > > @@ -18,13 +18,13 @@ extern "C" {
> > > * Tracepoint group naming format for DTrace providers. Providers may append
> > > * to this format string as needed.
> > > *
> > > - * GROUP_DATA provides the necessary data items to populate the format string
> > > - * (PID of the dtrace process and the provider name). GROUP_SFMT is like
> > > - * GROUP_FMT, but for sscanf().
> > > + * PROBE_DATA provides the necessary data items to populate the format string.
> > > + * PROBE_FMT formats that data.
> > > + * PROBE_SFMT is a format string for recognizing PROBE_FMT data in sscanf().
> > > */
> > > -#define GROUP_FMT "dt_%d_%s"
> > > -#define GROUP_SFMT "dt_%d_%ms"
> > > -#define GROUP_DATA getpid(), prvname
> > > +#define PROBE_DATA getpid(), prp->desc->prv, prp->desc->prb
> > > +#define PROBE_FMT "dt_%d_%s/%s"
> > > +#define PROBE_SFMT "dt_%d_%ms"
> > > typedef struct tp_probe tp_probe_t;
> > > diff --git a/test/unittest/providers/rawfbt/tst.wildcard-provider.d b/test/unittest/providers/rawfbt/tst.wildcard-provider.d
> > > new file mode 100644
> > > index 000000000..ad9f4c779
> > > --- /dev/null
> > > +++ b/test/unittest/providers/rawfbt/tst.wildcard-provider.d
> > > @@ -0,0 +1,20 @@
> > > +/*
> > > + * Oracle Linux DTrace.
> > > + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
> > > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > > + * http://oss.oracle.com/licenses/upl.
> > > + */
> > > +
> > > +/*
> > > + * ASSERTION: rawfbt probes can be found even when a wildcard provider
> > > + * description also allows fbt probes.
> > > + */
> > > +
> > > +#pragma D option quiet
> > > +
> > > +BEGIN,
> > > +*fbt:vmlinux:do_sys_open*:entry
> > > +{
> > > + printf("success\n");
> > > + exit(0);
> > > +}
> > I am confused how this test accomplishes verification of the assertion. If
> > a regular FBT probe satisfies the probe description, wouldn't this pass also?
> > Wouldn't a -l based test be better here, where you can test that the output
> > does indeed report both the fbt probe and the rawfbt probe that match?
>
> It appears that -l is not an issue; a -l test does not show the problem.
> The test in the patch is derived from the user bug report that motivated
> this patch.
>
> The whole prvname problem is that the bad prvname value makes GROUP_DATA
> bad, which makes FBT_GROUP_DATA bad, which is an issue only in kprobe_attach
> (and detach). So, we need kprobe_attach() to see the problem.
Ok, so yes, -l is not sufficient. But still, even if the test is derived from
the original reported problem, it still looks wrong to me. Or rather, the test
can pass when
fbt:vmlinux:do_sys+open*:entry exists
rawfbt:vmlinux:do_sys+open*:entry does NOT exist
because as long as 1 probe matches the probe specification, compilation will
succeed (and at runtime, the probe firing will complete the success criterium).
But that is not a valid PASS result for the assertion that is posed for this
test. If you are specifically looking for a rawfbt probe using a wildcard, you
might want to use r*fbt:vmlinux:do_sys+open*:entry instead perhaps?
> > > diff --git a/test/unittest/providers/rawfbt/tst.wildcard-provider.r b/test/unittest/providers/rawfbt/tst.wildcard-provider.r
> > > new file mode 100644
> > > index 000000000..b34a52d2f
> > > --- /dev/null
> > > +++ b/test/unittest/providers/rawfbt/tst.wildcard-provider.r
> > > @@ -0,0 +1,2 @@
> > > +success
> > > +
> > > --
> > > 2.47.3
> > >
More information about the DTrace-devel
mailing list