public inbox for dtrace@lists.linux.dev
 help / color / mirror / Atom feed
* [PATCH 1/6] Deferred attach of underlying USDT probes
@ 2024-09-28  2:21 eugene.loh
  2024-09-28  2:21 ` [PATCH 2/6] test: Correct long-standing dt_flags typo eugene.loh
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: eugene.loh @ 2024-09-28  2:21 UTC (permalink / raw)
  To: dtrace, dtrace-devel

From: Eugene Loh <eugene.loh@oracle.com>

We would like dtrace to trace USDT processes that start
even after the dtrace session has been launched.  In that
case, the underlying probe cannot be attached when dtrace
starts up;  rather, the BPF program must be attached once
the USDT process has been detected.

Therefore:

*)  Make dt_bpf_load_prog() callable outside of dt_bpf.c.

*)  Have update_uprobe() call dt_construct(), dt_link(),
    dt_bpf_load_prog(), and attach() for any new underlying
    probes.

Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
---
 libdtrace/dt_bpf.c         |  2 +-
 libdtrace/dt_bpf.h         |  3 ++
 libdtrace/dt_prov_uprobe.c | 65 ++++++++++++++++++++++++++++++++++++--
 3 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
index 90881e398..ab97be2cf 100644
--- a/libdtrace/dt_bpf.c
+++ b/libdtrace/dt_bpf.c
@@ -1134,7 +1134,7 @@ dt_bpf_reloc_prog(dtrace_hdl_t *dtp, const dtrace_difo_t *dp)
  *
  * Note that DTrace generates BPF programs that are licensed under the GPL.
  */
-static int
+int
 dt_bpf_load_prog(dtrace_hdl_t *dtp, const dt_probe_t *prp,
 		 const dtrace_difo_t *dp, uint_t cflags)
 {
diff --git a/libdtrace/dt_bpf.h b/libdtrace/dt_bpf.h
index 5716d2320..115adfbf0 100644
--- a/libdtrace/dt_bpf.h
+++ b/libdtrace/dt_bpf.h
@@ -14,6 +14,7 @@
 #include <dtrace/difo.h>
 #include <dt_btf.h>
 #include <dt_impl.h>
+#include <dt_probe.h>
 
 struct dtrace_hdl;
 
@@ -88,6 +89,8 @@ extern int dt_bpf_prog_load(struct dtrace_hdl *, const struct dt_probe *prp,
 			    size_t sz);
 extern int dt_bpf_raw_tracepoint_open(const void *tp, int fd);
 extern int dt_bpf_make_progs(struct dtrace_hdl *, uint_t);
+extern int dt_bpf_load_prog(dtrace_hdl_t *dtp, const dt_probe_t *prp,
+			    const dtrace_difo_t *dp, uint_t cflags);
 extern int dt_bpf_load_progs(struct dtrace_hdl *, uint_t);
 extern void dt_bpf_init(struct dtrace_hdl *dtp);
 
diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
index cf0a95fba..8fda85532 100644
--- a/libdtrace/dt_prov_uprobe.c
+++ b/libdtrace/dt_prov_uprobe.c
@@ -309,6 +309,10 @@ static int update_uprobe(dtrace_hdl_t *dtp, void *datap)
 	int		i, prid = dtp->dt_probe_id;
 	uint_t		old_strlen = dtp->dt_strlen;
 	dt_pcb_t	pcb;
+	dtrace_optval_t	dest_ok = DTRACEOPT_UNSET;
+
+	/* Determine whether destructive actions are okay. */
+	dtrace_getopt(dtp, "destructive", &dest_ok);
 
 	/* Clear stale pids. */
 	purge_BPFmap(dtp);
@@ -364,6 +368,61 @@ static int update_uprobe(dtrace_hdl_t *dtp, void *datap)
 
 		prp_next = dt_list_next(prp);
 
+		/* Handle underlying probe. */
+		if (prp->prov->impl == &dt_uprobe) {
+			dtrace_difo_t   *dp;
+			int		cflags, fd, rc = -1;
+
+			/*
+			 * Strictly speaking, we want the value passed in to
+			 * dtrace_go().  In practice, its flags pertain to
+			 * compilation and disassembly, which at this stage
+			 * no longer interest us.
+			 */
+			cflags = 0;
+
+			/* Check if the probe is already set up. */
+			if (prp->difo)
+				continue;
+
+			/* Make program. */
+			dp = dt_construct(dtp, prp, cflags, NULL);
+			if (dp == NULL)
+				continue;        // FIXME in dt_bpf_make_progs() this is a fatal error; should we do the same here?
+			prp->difo = dp;
+
+			/* Load program. */
+			if (dt_link(dtp, prp, dp, NULL) == -1)
+				continue;        // FIXME in dt_bpf_load_progs() this is a fatal error; should we do the same here?
+			if (dp->dtdo_flags & DIFOFLG_DESTRUCTIVE &&
+			    dest_ok == DTRACEOPT_UNSET)
+				return dt_set_errno(dtp, EDT_DESTRUCTIVE);
+
+			fd = dt_bpf_load_prog(dtp, prp, dp, cflags);
+			if (fd == -1)
+				continue;        // FIXME in dt_bpf_load_progs() this is a fatal error; should we do the same here?
+
+			if (prp->prov->impl->attach)
+				rc = prp->prov->impl->attach(dtp, prp, fd);
+
+			if (rc == -ENOTSUPP) {
+				char    *s;
+
+				close(fd);
+				if (asprintf(&s, "Failed to enable %s:%s:%s:%s",
+					      prp->desc->prv, prp->desc->mod,
+					      prp->desc->fun, prp->desc->prb) == -1)
+					return dt_set_errno(dtp, EDT_ENABLING_ERR);
+				dt_handle_rawerr(dtp, s);
+				free(s);
+			} else if (rc < 0) {
+				close(fd);
+				return dt_set_errno(dtp, EDT_ENABLING_ERR);
+			}
+
+			continue;
+		}
+
 		/* Make sure it is an overlying USDT probe. */
 		if (prp->prov->impl != &dt_usdt)
 			continue;
@@ -454,9 +513,11 @@ static int update_uprobe(dtrace_hdl_t *dtp, void *datap)
 				dt_bpf_map_update(dtp->dt_usdt_pridsmap_fd, &key, &val);
 			} else if (val.prid != oval.prid || val.mask != oval.mask) {
 				/*
-				 * This can happen when two overlying probes map to the same underlying probe for the same pid.
-				 * E.g., pid:::entry and pid:::0, or pid:::$offset and usdt:::.
+				 * Two different USDT probes should never map to the same
+				 * underlying probe for the same pid.  Nor should the bit
+				 * mask ever change.
 				 */
+				assert(0);
 			} else {
 				/*
 				 * Nothing to do, it already is in the map.
-- 
2.43.5


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-10-28 20:32 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-28  2:21 [PATCH 1/6] Deferred attach of underlying USDT probes eugene.loh
2024-09-28  2:21 ` [PATCH 2/6] test: Correct long-standing dt_flags typo eugene.loh
2024-10-25 20:48   ` Kris Van Hees
2024-09-28  2:21 ` [PATCH 3/6] test: Remove some outdated and unhelpful comments eugene.loh
2024-10-25 20:53   ` Kris Van Hees
2024-09-28  2:21 ` [PATCH 4/6] test: Add a USDT "deferred" test trigger eugene.loh
2024-10-28 20:32   ` Kris Van Hees
2024-09-28  2:21 ` [PATCH 5/6] test: Add USDT tests for deferred detection eugene.loh
2024-09-28  2:21 ` [PATCH 6/6] test: Add USDT error tests for -w and -Z eugene.loh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox