[DTrace-devel] [PATCH v2 04/04] rawtp: retrieve probe arguments from CTF data
Kris Van Hees
kris.van.hees at oracle.com
Thu Nov 30 15:59:09 UTC 2023
We were determining the number of arguments using a trial-and-error
approach with minimal BPF programs. If there is CTF type data for
the raw tracepoints (in the form of a function prototype), we use
that because it also gives us the types of the arguments.
If no such CTF data is available, we fall back to the trial-and-error
approach.
The included test will fail if the fallback is used. There is no way
to force the fallback to get triggered explicitly.
Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
libdtrace/dt_prov_rawtp.c | 95 +++++++++++++++++--
.../rawtp/tst.lv-sched_process_fork.r | 16 ++++
.../rawtp/tst.lv-sched_process_fork.r.p | 7 ++
.../rawtp/tst.lv-sched_process_fork.sh | 11 +++
4 files changed, 119 insertions(+), 10 deletions(-)
create mode 100644 test/unittest/providers/rawtp/tst.lv-sched_process_fork.r
create mode 100755 test/unittest/providers/rawtp/tst.lv-sched_process_fork.r.p
create mode 100755 test/unittest/providers/rawtp/tst.lv-sched_process_fork.sh
diff --git a/libdtrace/dt_prov_rawtp.c b/libdtrace/dt_prov_rawtp.c
index 93a30bb7..2d6d6eb5 100644
--- a/libdtrace/dt_prov_rawtp.c
+++ b/libdtrace/dt_prov_rawtp.c
@@ -157,18 +157,24 @@ static int trampoline(dt_pcb_t *pcb, uint_t exitlbl)
return 0;
}
-static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
- int *argcp, dt_argdesc_t **argvp)
+/*
+ * If there is no btf_trace_* prototype available in CTF, we can still probe
+ * the number of available argument for a raw tracepoint by means of a trial
+ * and error loop to see what the highest argument index is that the BPF
+ * verifier allows us to load from.
+ */
+static int probe_info_bpf(dtrace_hdl_t *dtp, const dt_probe_t *prp,
+ int *argcp, dt_argdesc_t **argvp)
{
int argc, i;
dt_argdesc_t *argv = NULL;
/*
- * This is an unfortunate necessity. The BPF verifier will not allow
- * us to access more argument values than are passed to the raw
- * tracepoint but the number of argument values for any given raw
- * tracepoint is not made available to userspace. So we use a trial
- * and error loop to see what the BPF verifier accepts.
+ * The BPF verifier will not allow us to access more argument values
+ * than are passed to the raw tracepoint but the number of argument
+ * values for any given raw tracepoint is not made available to
+ * userspace. So we use a trial and error loop to see what the BPF
+ * verifier accepts.
*/
for (argc = ARRAY_SIZE(((dt_mstate_t *)0)->argv); argc > 0; argc--) {
int bpf_fd, rtp_fd;
@@ -205,10 +211,79 @@ static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
}
done:
- *argcp = argc;
- *argvp = argv;
+ *argcp = argc;
+ *argvp = argv;
+
+ return 0;
+}
+
+static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
+ int *argcp, dt_argdesc_t **argvp)
+{
+#ifdef HAVE_LIBCTF
+ int rc, i;
+ char *str;
+ ctf_dict_t *ctfp;
+ ctf_id_t type;
+ int argc = 0;
+ dt_argdesc_t *argv = NULL;
+ ctf_funcinfo_t fi;
+ dtrace_typeinfo_t sym;
+ ctf_id_t *argt;
+
+ if (asprintf(&str, "btf_trace_%s", prp->desc->prb) == -1)
+ longjmp(yypcb->pcb_jmpbuf, 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_TYPEDEF)
+ goto use_alt;
+
+ ctfp = sym.dtt_ctfp;
+ type = ctf_type_reference(ctfp, sym.dtt_type);
+ if (ctf_type_kind(ctfp, type) != CTF_K_POINTER)
+ goto use_alt;
+ type = ctf_type_reference(ctfp, type);
+ if (ctf_type_kind(ctfp, type) != CTF_K_FUNCTION)
+ goto use_alt;
+ if (ctf_func_type_info(ctfp, type, &fi) == -1)
+ goto use_alt;
+
+ /*
+ * Raw tracepoints have an extra first argument for the context, so we
+ * need to skip that. (We also handle the case where fi.ctc_argc is 0
+ * even though that is not supposed to happen.)
+ */
+ if (fi.ctc_argc <= 1)
+ goto done;
+
+ argc = fi.ctc_argc;
+ argt = dt_calloc(dtp, argc, sizeof(ctf_id_t));
+ ctf_func_type_args(ctfp, type, argc, argt);
+
+ argc--;
+ argv = dt_zalloc(dtp, argc * sizeof(dt_argdesc_t));
+
+ for (i = 0; i < argc; i++) {
+ char n[DT_TYPE_NAMELEN];
+
+ ctf_type_name(ctfp, argt[i + 1], n, sizeof(n));
+ argv[i].mapping = i;
+ argv[i].native = strdup(n);
+ argv[i].xlate = NULL;
+ }
+
+ free(argt);
+
+done:
+ *argcp = argc;
+ *argvp = argv;
+
+ return 0;
- return 0;
+use_alt:
+#endif
+ return probe_info_bpf(dtp, prp, argcp, argvp);
}
dt_provimpl_t dt_rawtp = {
diff --git a/test/unittest/providers/rawtp/tst.lv-sched_process_fork.r b/test/unittest/providers/rawtp/tst.lv-sched_process_fork.r
new file mode 100644
index 00000000..de9304ca
--- /dev/null
+++ b/test/unittest/providers/rawtp/tst.lv-sched_process_fork.r
@@ -0,0 +1,16 @@
+PROBE rawtp sched sched_process_fork
+
+ Probe Description Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: ISA
+
+ Argument Types
+ args[0]: TYPE-OK
+ args[1]: TYPE-OK
+
diff --git a/test/unittest/providers/rawtp/tst.lv-sched_process_fork.r.p b/test/unittest/providers/rawtp/tst.lv-sched_process_fork.r.p
new file mode 100755
index 00000000..e83bac90
--- /dev/null
+++ b/test/unittest/providers/rawtp/tst.lv-sched_process_fork.r.p
@@ -0,0 +1,7 @@
+#!/usr/bin/awk -f
+NR == 1 { next; }
+NR == 2 { print "PROBE", $2, $3, $NF; next; }
+/args\[[0-9]+\]: uint64_t$/ { sub(/:.*$/, ": TYPE-OK"); }
+/args\[[0-9]+\]: struct task_struct \*$/ { sub(/:.*$/, ": TYPE-OK"); }
+/^ *[0-9]+/ { exit; }
+{ print; }
diff --git a/test/unittest/providers/rawtp/tst.lv-sched_process_fork.sh b/test/unittest/providers/rawtp/tst.lv-sched_process_fork.sh
new file mode 100755
index 00000000..bbfb7749
--- /dev/null
+++ b/test/unittest/providers/rawtp/tst.lv-sched_process_fork.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Oracle Linux DTrace.
+# Copyright (c) 2023, 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.
+
+dtrace=$1
+
+$dtrace $dt_flags -lvn rawtp:::sched_process_fork
+exit $?
--
2.42.0
More information about the DTrace-devel
mailing list