[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