[DTrace-devel] [PATCH v2 16/38] Add provider-specific probe_add_clause() for USDT tracing
eugene.loh at oracle.com
eugene.loh at oracle.com
Fri Jul 19 04:02:29 UTC 2024
From: Eugene Loh <eugene.loh at oracle.com>
To support USDT tracing of processes that start after the dtrace
session starts, we will move to a new USDT trampoline. Based on
the firing pid, it will look a bit mask up in a BPF map. It will
walk all its clauses, calling conditionally those clauses that are
in the map for that particular pid (overlying probe).
Thus, for each underlying probe, we need a list of clauses.
There is already a dt_probe_add_clause(). It adds clauses to
overlying probes.
Add the ability for a provider to supply a provider-specific
probe_add_clause() function.
Have the pid and USDT providers supply such a function that adds
a clause to an overlying probe's underlying probes.
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
libdtrace/dt_impl.h | 5 +++++
libdtrace/dt_probe.c | 7 ++-----
libdtrace/dt_prov_uprobe.c | 34 ++++++++++++++++++++++++++++++++++
libdtrace/dt_provider.h | 3 +++
4 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index d15c238c..2132eda2 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -283,6 +283,11 @@ typedef struct dt_percpu_drops {
typedef uint32_t dt_version_t; /* encoded version (see below) */
+typedef struct dt_probe_clause {
+ dt_list_t list;
+ dt_ident_t *clause;
+} dt_probe_clause_t;
+
struct dtrace_hdl {
const dtrace_vector_t *dt_vector; /* library vector, if vectored open */
void *dt_varg; /* vector argument, if vectored open */
diff --git a/libdtrace/dt_probe.c b/libdtrace/dt_probe.c
index 0b53121a..48b02e11 100644
--- a/libdtrace/dt_probe.c
+++ b/libdtrace/dt_probe.c
@@ -24,11 +24,6 @@
#include <dt_list.h>
#include <dt_bpf.h>
-typedef struct dt_probe_clause {
- dt_list_t list;
- dt_ident_t *clause;
-} dt_probe_clause_t;
-
typedef struct dt_probe_dependent {
dt_list_t list;
dt_probe_t *probe;
@@ -1359,6 +1354,8 @@ dt_probe_add_clause(dtrace_hdl_t *dtp, dt_probe_t *prp, dt_ident_t *idp)
pcp->clause = idp;
dt_list_append(&prp->clauses, pcp);
+ if (prp->prov->impl->probe_add_clause)
+ return prp->prov->impl->probe_add_clause(dtp, prp, idp);
return 0;
}
diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
index c77063a8..5dbd75e3 100644
--- a/libdtrace/dt_prov_uprobe.c
+++ b/libdtrace/dt_prov_uprobe.c
@@ -129,6 +129,38 @@ static void probe_destroy(dtrace_hdl_t *dtp, void *datap)
free_probe_list(dtp, datap);
}
+/*
+ * Add clause to probe.
+ */
+static int probe_add_clause(dtrace_hdl_t *dtp, dt_probe_t *prp, dt_ident_t *idp)
+{
+ const list_probe_t *pup;
+
+ for (pup = prp->prv_data; pup != NULL; pup = dt_list_next(pup)) {
+ dt_probe_t *uprp = pup->probe;
+ dt_probe_clause_t *prev, *pcp;
+
+ /*
+ * Check if the clause is already there. Since the clauses
+ * are added "in order," we only need to check the previous
+ * entry.
+ */
+ prev = dt_list_prev(&uprp->clauses);
+ if (prev && strcmp(prev->clause->di_name, idp->di_name) == 0)
+ continue;
+
+ /*
+ * Add the clause.
+ */
+ pcp = dt_zalloc(dtp, sizeof(dt_probe_clause_t));
+ if (pcp == NULL)
+ return -1;
+ pcp->clause = idp;
+ dt_list_append(&uprp->clauses, pcp);
+ }
+
+ return 0;
+}
/*
* Look up or create an underlying (real) probe, corresponding directly to a
@@ -811,6 +843,7 @@ dt_provimpl_t dt_pid = {
.prog_type = BPF_PROG_TYPE_UNSPEC,
.provide_probe = &provide_pid_probe,
.enable = &enable_pid,
+ .probe_add_clause = &probe_add_clause,
.probe_destroy = &probe_destroy,
};
@@ -822,5 +855,6 @@ dt_provimpl_t dt_usdt = {
.prog_type = BPF_PROG_TYPE_UNSPEC,
.provide_probe = &provide_usdt_probe,
.enable = &enable_usdt,
+ .probe_add_clause = &probe_add_clause,
.probe_destroy = &probe_destroy,
};
diff --git a/libdtrace/dt_provider.h b/libdtrace/dt_provider.h
index 17b1844c..b1b1b1b8 100644
--- a/libdtrace/dt_provider.h
+++ b/libdtrace/dt_provider.h
@@ -62,6 +62,9 @@ typedef struct dt_provimpl {
int (*probe_info)(dtrace_hdl_t *dtp, /* get probe info */
const struct dt_probe *prp,
int *argcp, dt_argdesc_t **argvp);
+ int (*probe_add_clause)(dtrace_hdl_t *dtp, /* add clause to probe */
+ struct dt_probe *prp,
+ dt_ident_t *idp);
void (*detach)(dtrace_hdl_t *dtp, /* probe cleanup */
const struct dt_probe *prb);
void (*probe_destroy)(dtrace_hdl_t *dtp, /* free probe data */
--
2.43.5
More information about the DTrace-devel
mailing list