[DTrace-devel] [PATCH v3 15/19] Ignore clauses: some clauses are impossible regardless of uprp

eugene.loh at oracle.com eugene.loh at oracle.com
Fri Oct 25 06:34:23 UTC 2024


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

In ignore_clauses, for an underlying probe uprp, we try to
decide if we can safely ignore clause n.

Meanwhile, for some clauses, the probe description tells us the
clause will not be called for any USDT probe, regardless of the
underlying probe.  For example, "syscall::write:" can safely be
ignored, for all uprp.

Add clause flags to track a statement's status.  Specifically,
a flag may indicate that a statement can be excluded for every
possible USDT probe or included because it might be needed for
some possible USDT probe.

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
 libdtrace/dt_program.c     | 15 +++++++++++
 libdtrace/dt_program.h     |  3 +++
 libdtrace/dt_prov_uprobe.c | 53 ++++++++++++++++++++++++++++++++++++--
 libdtrace/dtrace.h         |  2 ++
 4 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/libdtrace/dt_program.c b/libdtrace/dt_program.c
index 45da4f206..23b91fb2e 100644
--- a/libdtrace/dt_program.c
+++ b/libdtrace/dt_program.c
@@ -20,6 +20,21 @@
 #include <dt_probe.h>
 #include <dt_bpf.h>
 
+int
+dt_stmt_clsflag_set(dtrace_stmtdesc_t *stp, int flags) {
+	stp->dtsd_clauseflags |= flags;
+
+	return 0;
+}
+
+int
+dt_stmt_clsflag_test(dtrace_stmtdesc_t *stp, int flags) {
+	if (stp->dtsd_clauseflags & flags)
+		return 1;
+
+	return 0;
+}
+
 dtrace_prog_t *
 dt_program_create(dtrace_hdl_t *dtp)
 {
diff --git a/libdtrace/dt_program.h b/libdtrace/dt_program.h
index 5f57e3615..5f11ef3a6 100644
--- a/libdtrace/dt_program.h
+++ b/libdtrace/dt_program.h
@@ -28,6 +28,9 @@ struct dtrace_prog {
 	uint8_t dp_dofversion;	/* DOF version this program requires */
 };
 
+extern int dt_stmt_clsflag_set(dtrace_stmtdesc_t *stp, int flags);
+extern int dt_stmt_clsflag_test(dtrace_stmtdesc_t *stp, int flags);
+
 extern dtrace_prog_t *dt_program_create(dtrace_hdl_t *);
 extern void dt_program_destroy(dtrace_hdl_t *, dtrace_prog_t *);
 
diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
index 11ff01051..9ca190b72 100644
--- a/libdtrace/dt_prov_uprobe.c
+++ b/libdtrace/dt_prov_uprobe.c
@@ -27,6 +27,7 @@
  */
 #include <sys/types.h>
 #include <assert.h>
+#include <ctype.h>
 #include <errno.h>
 #include <string.h>
 
@@ -37,6 +38,7 @@
 #include "dt_list.h"
 #include "dt_provider_tp.h"
 #include "dt_probe.h"
+#include "dt_program.h"
 #include "dt_pid.h"
 #include "dt_string.h"
 #include "port.h"
@@ -270,7 +272,53 @@ clean_usdt_probes(dtrace_hdl_t *dtp)
 static int
 ignore_clause(dtrace_hdl_t *dtp, int n, const dt_probe_t *uprp)
 {
-	/* To be safe, ignore nothing. */
+	dtrace_stmtdesc_t	*stp = dtp->dt_stmts[n];
+	dtrace_probedesc_t	*pdp = &stp->dtsd_ecbdesc->dted_probe;
+
+	/*
+	 * Some clauses could never be called for a USDT probe,
+	 * regardless of the underlying probe uprp.  Cache this
+	 * status in the clause flags for dt_stmts[n].
+	 */
+	if (dt_stmt_clsflag_test(stp, DT_CLSFLAG_USDT_INCLUDE | DT_CLSFLAG_USDT_EXCLUDE) == 0) {
+		char lastchar = pdp->prv[strlen(pdp->prv) - 1];
+
+		/*
+		 * If the last char in the provider description is
+		 * neither '*' nor a digit, it cannot be a USDT probe.
+		 */
+		if (lastchar != '*' && !isdigit(lastchar)) {
+			dt_stmt_clsflag_set(stp, DT_CLSFLAG_USDT_EXCLUDE);
+			return 1;
+		}
+
+		/*
+		 * If the provider description is "pid[0-9]*", it
+		 * is a pid probe, not USDT.
+		 */
+		if (strncmp(pdp->prv, "pid", 3) == 0) {
+			int i, l = strlen(pdp->prv);
+
+			for (i = 3; i < l; i++)
+				if (!isdigit((pdp->prv[i])))
+					break;
+
+			if (i == l) {
+				dt_stmt_clsflag_set(stp, DT_CLSFLAG_USDT_EXCLUDE);
+				return 1;
+			}
+		}
+
+		/* Otherwise, it is possibly a USDT probe. */
+		dt_stmt_clsflag_set(stp, DT_CLSFLAG_USDT_INCLUDE);
+	}
+	if (dt_stmt_clsflag_test(stp, DT_CLSFLAG_USDT_EXCLUDE) == 1)
+		return 1;
+
+	/*
+	 * If we cannot ignore this statement, try to use uprp.
+	 */
+
 	return 0;
 }
 
@@ -453,7 +501,8 @@ static int discover(dtrace_hdl_t *dtp)
 		stp = dtp->dt_stmts[i];
 		if (stp == NULL)
 			continue;
-		dt_pid_create_usdt_probes(&stp->dtsd_ecbdesc->dted_probe, dtp, &pcb);
+		if (dt_stmt_clsflag_test(stp, DT_CLSFLAG_USDT_EXCLUDE) != 1)
+			dt_pid_create_usdt_probes(&stp->dtsd_ecbdesc->dted_probe, dtp, &pcb);
 	}
 
 	return 0;
diff --git a/libdtrace/dtrace.h b/libdtrace/dtrace.h
index e636c5065..20672d3fc 100644
--- a/libdtrace/dtrace.h
+++ b/libdtrace/dtrace.h
@@ -161,6 +161,8 @@ typedef struct dtrace_stmtdesc {
 #define DT_CLSFLAG_EXIT			16	/* exit */
 #define DT_CLSFLAG_DESTRUCT		32	/* destructive */
 #define DT_CLSFLAG_AGGREGATION		64	/* aggregation */
+#define DT_CLSFLAG_USDT_INCLUDE		128	/* could be used in USDT clause */
+#define DT_CLSFLAG_USDT_EXCLUDE		256	/* could not be used in USDT clause */
 
 typedef int dtrace_stmt_f(dtrace_hdl_t *dtp, dtrace_prog_t *pgp,
     dtrace_stmtdesc_t *sdp, void *data);
-- 
2.43.5




More information about the DTrace-devel mailing list