[DTrace-devel] [PATCH 2/2] rawfbt: prvname is not properly set

Kris Van Hees kris.van.hees at oracle.com
Thu Jan 15 22:18:11 UTC 2026


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).

>  		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?

> 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