[DTrace-devel] [PATCH 5/8] sdt: retrieve probe arguments from CTF data (if possible)

Eugene Loh eugene.loh at oracle.com
Thu Apr 4 22:11:17 UTC 2024


Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
though I don't mind if Nick also takes a look... particularly at the CTF 
stuff.  And a few more things...

On 4/3/24 11:26, Kris Van Hees via DTrace-devel wrote:
> We were determining the probe argument types based on data from the
> TRCAEFS/events/<group>/<probe>/format file.  If the CTF type for the

TRCAEFS typo

> trace event data struct can be found, we can use that instead.
>
> If no such CTF data is available, we fall back to the EVENTFS based
> approach.
>
> diff --git a/libdtrace/dt_prov_sdt.c b/libdtrace/dt_prov_sdt.c
> @@ -186,13 +186,45 @@ static int trampoline(dt_pcb_t *pcb, uint_t exitlbl)
>   
> +/*
> + * If thre is no trace_event_raw_* struct available in CTF, we can still get

thre typo

> + * argument count and type information from the tracefs data.
> + */
> +static int probe_info_tracefs(dtrace_hdl_t *dtp, const dt_probe_t *prp,
> +			      int *argcp, dt_argdesc_t **argvp)
> +{
> +	FILE				*f;
> +	char				*fn;
> +	int				rc;
> +	tp_probe_t			*tpp = prp->prv_data;
> +	const dtrace_probedesc_t	*pdp = prp->desc;
> +
> +	if (asprintf(&fn, EVENTSFS "%s/%s/format", pdp->mod, pdp->prb) == -1)
> +		return dt_set_errno(dtp, EDT_NOMEM);
> +
> +	f = fopen(fn, "r");
> +	free(fn);
> +	if (!f)
> +		return -ENOENT;
> +
> +	rc = dt_tp_event_info(dtp, f, 0, tpp, argcp, argvp);
> +	fclose(f);
> +
> +	return rc;
> +}
> +
>   static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
>   		      int *argcp, dt_argdesc_t **argvp)
>   {
> -	FILE		*f;
> -	char		fn[256];
> -	int		rc;
> -	tp_probe_t	*tpp = prp->prv_data;
> +	tp_probe_t		*tpp = prp->prv_data;
> +	int			rc, i;
> +	char			*str;
> +	ctf_dict_t		*ctfp;

There are a bunch of declarations here that should probably be wrapped 
in #ifdef HAVE_LIBCTF.  That should help with compiler warnings about 
unused variables but also presumably with unknown types like ctf_dict_t.

> +	ctf_id_t		type;
> +	ctf_next_t		*it = NULL;
> +	int			argc = 0;
> +	dt_argdesc_t		*argv = NULL;
> +	dtrace_typeinfo_t	sym;
>   
>   	/*
>   	 * If the tracepoint has already been created and we have its info,
> @@ -201,20 +233,55 @@ static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
>   	if (dt_tp_is_created(tpp))
>   		return -1;
>   
> -	strcpy(fn, EVENTSFS);
> -	strcat(fn, prp->desc->mod);
> -	strcat(fn, "/");
> -	strcat(fn, prp->desc->prb);
> -	strcat(fn, "/format");
> +#ifdef HAVE_LIBCTF
> +	if (asprintf(&str, "struct trace_event_raw_%s", prp->desc->prb) == -1)
> +		return dt_set_errno(dtp, EDT_NOMEM);
> +	rc = dtrace_lookup_by_type(dtp, DTRACE_OBJ_EVERY, str, &sym);
> +	free(str);
> +	if (rc ||
> +	    ctf_type_kind(sym.dtt_ctfp, sym.dtt_type) != CTF_K_STRUCT)
> +		goto use_alt;
>   
> -	f = fopen(fn, "r");
> -	if (!f)
> -		return -ENOENT;
> +	/*
> +	 * Tracepoints have an extra member at the beginning and end of the
> +	 * struct.  We need to skip those.  (We also handle the case where one
> +	 * or both of those members are missing even though that is not
> +	 * supposed to happen.)
> +	 */
> +	ctfp = sym.dtt_ctfp;
> +	type = sym.dtt_type;
> +	rc = ctf_member_count(ctfp, type);
> +	if (rc <= 2)
> +		goto done;
> +
> +	rc--;
> +	argc = rc - 1;
> +	argv = dt_zalloc(dtp, argc * sizeof(dt_argdesc_t));
> +	if (argv == NULL)
> +		return dt_set_errno(dtp, EDT_NOMEM);
> +	/* Skip first member. */
> +	ctf_member_next(ctfp, type, &it, NULL, NULL, 0);
> +	for (i = 0; i < argc; i++) {
> +		ctf_id_t	mtyp;
> +		char		n[DT_TYPE_NAMELEN];
> +
> +		if (ctf_member_next(ctfp, type, &it, NULL, &mtyp, 0) == CTF_ERR)
> +			return dt_set_errno(dtp, EDT_CTF);
> +		ctf_type_name(ctfp, mtyp, n, sizeof(n));
> +		argv[i].mapping = i;
> +		argv[i].native = strdup(n);
> +		argv[i].xlate = NULL;
> +	}
> +	ctf_next_destroy(it);
> +done:
> +	*argcp = argc;
> +	*argvp = argv;
>   
> -	rc = dt_tp_event_info(dtp, f, 0, tpp, argcp, argvp);
> -	fclose(f);
> +	return 0;
>   
> -	return rc;
> +use_alt:
> +#endif
> +	return probe_info_tracefs(dtp, prp, argcp, argvp);
>   }



More information about the DTrace-devel mailing list