[DTrace-devel] [PATCH v3] Support probeprov, probemod, probefunc, probename built-in variables

Eugene Loh eugene.loh at oracle.com
Sat Jun 12 22:11:22 PDT 2021


Reviewed-by: Eugene Loh <eugene.loh at oracle.com>

On 6/11/21 2:57 PM, Kris Van Hees wrote:
> This patch adds support for the built-in variables that provide the
> component names for the probe description of the current probe in a
> D clause, i.e. the probe that triggered the execution of the clause.
>
> Because clauses (compiled into BPF functions) can be linked into the
> BPF programs for multiple probes, the value of these built-in variables
> cannot be provided at compile time.  Their value is obtained from a
> new BPF hashmap named 'probes' that associates a probe id with the
> constant strings that provide the components of the probe description.
>
> This patch also introduces a new BPF constant (STBSZ, resolved at link
> time) to hold the size of the string constant table.  This value is
> needed to satisfy BPF verifier expectations for map value access
> boundary checking.
>
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
>   bpf/get_bvar.c                                | 36 +++++++++++++++++++
>   libdtrace/dt_bpf.c                            | 35 +++++++++++++++++-
>   libdtrace/dt_bpf.h                            |  1 +
>   libdtrace/dt_bpf_maps.h                       | 12 +++----
>   libdtrace/dt_cc.c                             |  3 ++
>   libdtrace/dt_dlibs.c                          |  4 +++
>   test/demo/builtin/probefunc.d                 |  1 -
>   test/demo/builtin/probemod.d                  |  1 -
>   test/demo/intro/trussrw.d                     |  3 +-
>   test/unittest/actions/system/tst.system-str.d |  3 +-
>   test/unittest/dif/strlen.d                    |  1 -
>   test/unittest/inline/tst.InlineKinds.d        |  3 +-
>   test/unittest/providers/tst.beginprof.d       |  3 +-
>   test/unittest/providers/tst.probattrs.d       |  3 +-
>   test/unittest/providers/tst.probefunc.d       |  3 +-
>   test/unittest/providers/tst.probemod.d        |  3 +-
>   test/unittest/providers/tst.probename.d       |  3 +-
>   test/unittest/providers/tst.probprov.d        |  3 +-
>   18 files changed, 92 insertions(+), 29 deletions(-)
>
> diff --git a/bpf/get_bvar.c b/bpf/get_bvar.c
> index 7e7b25a3..1618dfce 100644
> --- a/bpf/get_bvar.c
> +++ b/bpf/get_bvar.c
> @@ -9,8 +9,10 @@
>   #include <dtrace/conf.h>
>   #include <dtrace/dif_defines.h>
>   #include <dtrace/faults_defines.h>
> +#include <dt_bpf_maps.h>
>   #include <dt_dctx.h>
>   #include <dt_state.h>
> +#include <dt_varint.h>
>   
>   #include "probe_error.h"
>   
> @@ -19,8 +21,11 @@
>   #endif
>   
>   extern struct bpf_map_def cpuinfo;
> +extern struct bpf_map_def probes;
>   extern struct bpf_map_def state;
>   
> +extern uint64_t STBSZ;
> +
>   #define error(dctx, fault, illval) \
>   	({ \
>   		dt_probe_error((dctx), -1, (fault), (illval)); \
> @@ -52,6 +57,37 @@ noinline uint64_t dt_get_bvar(dt_dctx_t *dctx, uint32_t id)
>   		/* FIXME: no stack() yet */
>   		return 0;
>   	}
> +	case DIF_VAR_PROBEPROV:
> +	case DIF_VAR_PROBEMOD:
> +	case DIF_VAR_PROBEFUNC:
> +	case DIF_VAR_PROBENAME: {
> +		uint32_t	key;
> +		dt_bpf_probe_t	*pinfo;
> +		uint64_t	off;
> +
> +		key = mst->prid;
> +		pinfo = bpf_map_lookup_elem(&probes, &key);
> +		if (pinfo == NULL)
> +			return (uint64_t)dctx->strtab;
> +
> +		switch (id) {
> +		case DIF_VAR_PROBEPROV:
> +			off = pinfo->prv;
> +			break;
> +		case DIF_VAR_PROBEMOD:
> +			off = pinfo->mod;
> +			break;
> +		case DIF_VAR_PROBEFUNC:
> +			off = pinfo->fun;
> +			break;
> +		case DIF_VAR_PROBENAME:
> +			off = pinfo->prb;
> +		}
> +		if (off > (uint64_t)&STBSZ)
> +			return (uint64_t)dctx->strtab;
> +
> +		return (uint64_t)(dctx->strtab + off);
> +	}
>   	case DIF_VAR_PID: {
>   		uint64_t	val = bpf_get_current_pid_tgid();
>   
> diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
> index 2e63d5ee..a60d89cd 100644
> --- a/libdtrace/dt_bpf.c
> +++ b/libdtrace/dt_bpf.c
> @@ -17,7 +17,9 @@
>   #include <dt_dctx.h>
>   #include <dt_probe.h>
>   #include <dt_state.h>
> +#include <dt_strtab.h>
>   #include <dt_bpf.h>
> +#include <dt_bpf_maps.h>
>   #include <port.h>
>   
>   #include <bpf.h>
> @@ -138,6 +140,24 @@ set_task_offsets(dtrace_hdl_t *dtp)
>   	return 0;
>   }
>   
> +static void
> +populate_probes_map(dtrace_hdl_t *dtp, int fd)
> +{
> +	dt_probe_t	*prp;
> +
> +	for (prp = dt_list_next(&dtp->dt_enablings); prp != NULL;
> +	     prp = dt_list_next(prp)) {
> +		dt_bpf_probe_t	pinfo;
> +
> +		pinfo.prv = dt_strtab_index(dtp->dt_ccstab, prp->desc->prv);
> +		pinfo.mod = dt_strtab_index(dtp->dt_ccstab, prp->desc->mod);
> +		pinfo.fun = dt_strtab_index(dtp->dt_ccstab, prp->desc->fun);
> +		pinfo.prb = dt_strtab_index(dtp->dt_ccstab, prp->desc->prb);
> +
> +		dt_bpf_map_update(fd, &prp->desc->id, &pinfo);
> +	}
> +}
> +
>   /*
>    * Create the global BPF maps that are shared between all BPF programs in a
>    * single tracing session:
> @@ -173,6 +193,10 @@ set_task_offsets(dtrace_hdl_t *dtp)
>    *		consumer handle (dt_strlen), and increased by the maximum
>    *		string size to ensure that the BPF verifier can validate all
>    *		access requests for dynamic references to string constants.
> + * - probes:	Probe information map.  This is a global map indexed by probe
> + *		ID.  The value is a struct that contains static probe info.
> + *		The map only contains entries for probes that are actually in
> + *		use.
>    * - gvars:	Global variables map.  This is a global map with a singleton
>    *		element (key 0) addressed by variable offset.
>    * - lvars:	Local variables map.  This is a per-CPU map with a singleton
> @@ -200,7 +224,7 @@ int
>   dt_bpf_gmap_create(dtrace_hdl_t *dtp)
>   {
>   	int		stabsz, gvarsz, lvarsz, tvarc, aggsz;
> -	int		ci_mapfd, st_mapfd;
> +	int		ci_mapfd, st_mapfd, pr_mapfd;
>   	uint32_t	key = 0;
>   
>   	/* If we already created the global maps, return success. */
> @@ -274,6 +298,12 @@ dt_bpf_gmap_create(dtrace_hdl_t *dtp)
>   	if (st_mapfd == -1)
>   		return -1;		/* dt_errno is set for us */
>   
> +	pr_mapfd = create_gmap(dtp, "probes", BPF_MAP_TYPE_HASH,
> +			       sizeof(uint32_t), sizeof(dt_bpf_probe_t),
> +			       dt_list_length(&dtp->dt_enablings));
> +	if (pr_mapfd == -1)
> +		return -1;		/* dt_errno is set for us */
> +
>   	if (gvarsz > 0 &&
>   	    create_gmap(dtp, "gvars", BPF_MAP_TYPE_ARRAY,
>   			sizeof(uint32_t), gvarsz, 1) == -1)
> @@ -295,6 +325,9 @@ dt_bpf_gmap_create(dtrace_hdl_t *dtp)
>   	/* Populate the 'strtab' map. */
>   	dt_bpf_map_update(st_mapfd, &key, dtp->dt_strtab);
>   
> +	/* Populate the 'probes' map. */
> +	populate_probes_map(dtp, pr_mapfd);
> +
>   	/* Set some task_struct offsets in state. */
>   	if (set_task_offsets(dtp))
>   		return dt_set_errno(dtp, EDT_CTF);
> diff --git a/libdtrace/dt_bpf.h b/libdtrace/dt_bpf.h
> index 4a9e598a..7fa9eed3 100644
> --- a/libdtrace/dt_bpf.h
> +++ b/libdtrace/dt_bpf.h
> @@ -22,6 +22,7 @@ extern "C" {
>   #define DT_CONST_PRID	2
>   #define DT_CONST_CLID	3
>   #define DT_CONST_ARGC	4
> +#define DT_CONST_STBSZ	5
>   
>   extern int perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu,
>   			   int group_fd, unsigned long flags);
> diff --git a/libdtrace/dt_bpf_maps.h b/libdtrace/dt_bpf_maps.h
> index 12c2e8d8..aa088ce8 100644
> --- a/libdtrace/dt_bpf_maps.h
> +++ b/libdtrace/dt_bpf_maps.h
> @@ -1,6 +1,6 @@
>   /*
>    * Oracle Linux DTrace.
> - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2019, 2021, 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.
>    */
> @@ -8,22 +8,20 @@
>   #ifndef _DT_BPF_MAPS_H
>   #define _DT_BPF_MAPS_H
>   
> -#ifdef FIXME
>   #ifdef  __cplusplus
>   extern "C" {
>   #endif
>   
>   typedef struct dt_bpf_probe	dt_bpf_probe_t;
>   struct dt_bpf_probe {
> -	uint_t		prvv;		/* probeprov string offset in strtab */
> -	uint_t		mod;		/* probemod string offset in strtab */
> -	uint_t		fun;		/* probefunc string offset in strtab */
> -	uint_t		prb;		/* probename string offset in strtab */
> +	size_t		prv;		/* probeprov string offset in strtab */
> +	size_t		mod;		/* probemod string offset in strtab */
> +	size_t		fun;		/* probefunc string offset in strtab */
> +	size_t		prb;		/* probename string offset in strtab */
>   };
>   
>   #ifdef  __cplusplus
>   }
>   #endif
> -#endif
>   
>   #endif /* _DT_BPF_FUNCS_H */
> diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
> index 2afbd660..86b06237 100644
> --- a/libdtrace/dt_cc.c
> +++ b/libdtrace/dt_cc.c
> @@ -2323,6 +2323,9 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
>   			case DT_CONST_ARGC:
>   				nrp->dofr_data = 0;	/* FIXME */
>   				continue;
> +			case DT_CONST_STBSZ:
> +				nrp->dofr_data = dtp->dt_strlen;
> +				continue;
>   			default:
>   				/* probe name -> value is probe id */
>   				if (strchr(idp->di_name, ':') != NULL)
> diff --git a/libdtrace/dt_dlibs.c b/libdtrace/dt_dlibs.c
> index 6dae65d5..fae58b1a 100644
> --- a/libdtrace/dt_dlibs.c
> +++ b/libdtrace/dt_dlibs.c
> @@ -68,6 +68,7 @@ static const dt_ident_t		dt_bpf_symbols[] = {
>   	DT_BPF_SYMBOL(gvars, DT_IDENT_PTR),
>   	DT_BPF_SYMBOL(lvars, DT_IDENT_PTR),
>   	DT_BPF_SYMBOL(mem, DT_IDENT_PTR),
> +	DT_BPF_SYMBOL(probes, DT_IDENT_PTR),
>   	DT_BPF_SYMBOL(state, DT_IDENT_PTR),
>   	DT_BPF_SYMBOL(strtab, DT_IDENT_PTR),
>   	DT_BPF_SYMBOL(tvars, DT_IDENT_PTR),
> @@ -76,6 +77,7 @@ static const dt_ident_t		dt_bpf_symbols[] = {
>   	DT_BPF_SYMBOL_ID(PRID, DT_IDENT_SCALAR, DT_CONST_PRID),
>   	DT_BPF_SYMBOL_ID(CLID, DT_IDENT_SCALAR, DT_CONST_CLID),
>   	DT_BPF_SYMBOL_ID(ARGC, DT_IDENT_SCALAR, DT_CONST_ARGC),
> +	DT_BPF_SYMBOL_ID(STBSZ, DT_IDENT_SCALAR, DT_CONST_STBSZ),
>   	/* End-of-list marker */
>   	{ NULL, }
>   };
> @@ -414,6 +416,8 @@ get_symbols(dtrace_hdl_t *dtp, Elf *elf, int syms_idx, int strs_idx,
>   			idp = dt_dlib_get_map(dtp, name);
>   			if (idp == NULL)
>   				idp = dt_dlib_get_func(dtp, name);
> +			if (idp == NULL)
> +				idp = dt_dlib_get_var(dtp, name);
>   			if (idp == NULL) {
>   				dt_dlib_error(dtp, D_IDENT_UNDEF,
>   					      "undefined symbol %s in BPF dlib",
> diff --git a/test/demo/builtin/probefunc.d b/test/demo/builtin/probefunc.d
> index 9f9b9147..ed2bff00 100644
> --- a/test/demo/builtin/probefunc.d
> +++ b/test/demo/builtin/probefunc.d
> @@ -1,4 +1,3 @@
> -/* @@xfail: dtv2 */
>   BEGIN {
>   	trace(probefunc);
>   	exit(0);
> diff --git a/test/demo/builtin/probemod.d b/test/demo/builtin/probemod.d
> index eed55f10..5796bdc2 100644
> --- a/test/demo/builtin/probemod.d
> +++ b/test/demo/builtin/probemod.d
> @@ -1,4 +1,3 @@
> -/* @@xfail: dtv2 */
>   BEGIN {
>   	trace(probemod);
>   	exit(0);
> diff --git a/test/demo/intro/trussrw.d b/test/demo/intro/trussrw.d
> index 24cb5998..e1a17099 100644
> --- a/test/demo/intro/trussrw.d
> +++ b/test/demo/intro/trussrw.d
> @@ -1,11 +1,10 @@
>   /*
>    * Oracle Linux DTrace.
> - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2005, 2021, 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.
>    */
>   
> -/* @@xfail: dtv2 */
>   /* @@trigger: mmap */
>   
>   syscall::read:entry,
> diff --git a/test/unittest/actions/system/tst.system-str.d b/test/unittest/actions/system/tst.system-str.d
> index 70b67e2a..8f532ae6 100644
> --- a/test/unittest/actions/system/tst.system-str.d
> +++ b/test/unittest/actions/system/tst.system-str.d
> @@ -1,10 +1,9 @@
>   /*
>    * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2021, 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.
>    */
> -/* @@xfail: dtv2 */
>   
>   #pragma D option quiet
>   #pragma D option destructive
> diff --git a/test/unittest/dif/strlen.d b/test/unittest/dif/strlen.d
> index f801562d..b8f419d2 100644
> --- a/test/unittest/dif/strlen.d
> +++ b/test/unittest/dif/strlen.d
> @@ -1,4 +1,3 @@
> -/* @@xfail: dtv2 */
>   BEGIN
>   {
>   	trace(strlen(probename));
> diff --git a/test/unittest/inline/tst.InlineKinds.d b/test/unittest/inline/tst.InlineKinds.d
> index 0b8bf8cd..5f2ec1b8 100644
> --- a/test/unittest/inline/tst.InlineKinds.d
> +++ b/test/unittest/inline/tst.InlineKinds.d
> @@ -1,10 +1,9 @@
>   /*
>    * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2021, 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.
>    */
> -/* @@xfail: dtv2 */
>   
>   /*
>    * Test the code generation and results of the various kinds of inlines.
> diff --git a/test/unittest/providers/tst.beginprof.d b/test/unittest/providers/tst.beginprof.d
> index c041dc34..2b97718a 100644
> --- a/test/unittest/providers/tst.beginprof.d
> +++ b/test/unittest/providers/tst.beginprof.d
> @@ -1,10 +1,9 @@
>   /*
>    * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2021, 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.
>    */
> -/* @@xfail: dtv2 */
>   
>   /*
>    * ASSERTION:
> diff --git a/test/unittest/providers/tst.probattrs.d b/test/unittest/providers/tst.probattrs.d
> index ed77fe5a..af42a6b0 100644
> --- a/test/unittest/providers/tst.probattrs.d
> +++ b/test/unittest/providers/tst.probattrs.d
> @@ -1,10 +1,9 @@
>   /*
>    * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2021, 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.
>    */
> -/* @@xfail: dtv2 */
>   
>   /*
>    * ASSERTION:
> diff --git a/test/unittest/providers/tst.probefunc.d b/test/unittest/providers/tst.probefunc.d
> index 86b8f7ea..0f4c7980 100644
> --- a/test/unittest/providers/tst.probefunc.d
> +++ b/test/unittest/providers/tst.probefunc.d
> @@ -1,10 +1,9 @@
>   /*
>    * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2021, 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.
>    */
> -/* @@xfail: dtv2 */
>   
>   /*
>    * ASSERTION:
> diff --git a/test/unittest/providers/tst.probemod.d b/test/unittest/providers/tst.probemod.d
> index 2dace056..fc20a4c7 100644
> --- a/test/unittest/providers/tst.probemod.d
> +++ b/test/unittest/providers/tst.probemod.d
> @@ -1,10 +1,9 @@
>   /*
>    * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2021, 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.
>    */
> -/* @@xfail: dtv2 */
>   
>   /*
>    * ASSERTION:
> diff --git a/test/unittest/providers/tst.probename.d b/test/unittest/providers/tst.probename.d
> index b486030b..462d07f4 100644
> --- a/test/unittest/providers/tst.probename.d
> +++ b/test/unittest/providers/tst.probename.d
> @@ -1,10 +1,9 @@
>   /*
>    * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2021, 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.
>    */
> -/* @@xfail: dtv2 */
>   
>   /*
>    * ASSERTION:
> diff --git a/test/unittest/providers/tst.probprov.d b/test/unittest/providers/tst.probprov.d
> index da5d67f0..faac3658 100644
> --- a/test/unittest/providers/tst.probprov.d
> +++ b/test/unittest/providers/tst.probprov.d
> @@ -1,10 +1,9 @@
>   /*
>    * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2021, 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.
>    */
> -/* @@xfail: dtv2 */
>   
>   /*
>    * ASSERTION:



More information about the DTrace-devel mailing list