[DTrace-devel] [PATCH 6/7] Populate sdt probe argument data based on argument types

Kris Van Hees kris.van.hees at oracle.com
Thu May 26 18:24:44 UTC 2022


Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 libdtrace/dt_prov_sdt.c                       |  44 ++++++++---
 test/unittest/sdt/tst.args.d                  |  69 +-----------------
 test/unittest/sdt/tst.args.r                  | Bin 77 -> 57 bytes
 .../variables/bvar/tst.args-match-argN.d      |  26 +++++++
 4 files changed, 65 insertions(+), 74 deletions(-)
 create mode 100644 test/unittest/variables/bvar/tst.args-match-argN.d

diff --git a/libdtrace/dt_prov_sdt.c b/libdtrace/dt_prov_sdt.c
index 854cfcf2..2ed2a210 100644
--- a/libdtrace/dt_prov_sdt.c
+++ b/libdtrace/dt_prov_sdt.c
@@ -1,6 +1,6 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022, 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.
  *
@@ -131,6 +131,8 @@ static void trampoline(dt_pcb_t *pcb)
 {
 	int		i;
 	dt_irlist_t	*dlp = &pcb->pcb_ir;
+	dt_probe_t	*prp = pcb->pcb_probe;
+	ssize_t		off;
 
 	dt_cg_tramp_prologue(pcb);
 
@@ -143,17 +145,41 @@ static void trampoline(dt_pcb_t *pcb)
 	dt_cg_tramp_clear_regs(pcb);
 
 	/*
-	 *	for (i = 0; i < argc; i++)
-	 *		dctx->mst->argv[i] = ((uint64_t *)ctx)[i + 1];
-	 *				//     (first value is private)
-	 *				// lddw %r0, [%r8 + (i + 1) * 8]
-	 *				// stdw [%r7 + DMST_ARG(i)], 0
+	 * Decode the arguments of the underlying tracepoint (from the context)
+	 * and store them in the cached argument list in the mstate.
+	 *
+	 * Skip the first argument (a private pointer that we are not allowed
+	 * to access from BPF).
 	 */
-	for (i = 0; i < pcb->pcb_pinfo.dtp_argc; i++) {
-		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, (i + 1) * 8));
-		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(i), BPF_REG_0));
+	off = sizeof(uint64_t);
+	for (i = 0; i < prp->argc; i++) {
+		dt_node_t	*anp = prp->xargv[i];
+		ssize_t		size = ctf_type_size(anp->dn_ctfp,
+						     anp->dn_type);
+		ssize_t		align = ctf_type_align(anp->dn_ctfp,
+						       anp->dn_type);
+
+		off = P2ROUNDUP(off, align);
+		if (dt_node_is_scalar(anp)) {
+			uint_t	ldsz = dt_cg_load(anp, anp->dn_ctfp,
+						  anp->dn_type, NULL);
+
+			emit(dlp, BPF_LOAD(ldsz, BPF_REG_0, BPF_REG_8, off));
+			emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(i), BPF_REG_0));
+		} else {
+			emit(dlp, BPF_MOV_REG(BPF_REG_0, BPF_REG_8));
+			emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, off));
+			emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(i), BPF_REG_0));
+		}
+		off += size;
 	}
 
+	/*
+	 * Clear the remainder of the cached arguments.
+	 */
+	for (; i < ARRAY_SIZE(((dt_mstate_t *)0)->argv); i++)
+		emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_ARG(i), 0));
+
 	dt_cg_tramp_epilogue(pcb);
 }
 
diff --git a/test/unittest/sdt/tst.args.d b/test/unittest/sdt/tst.args.d
index 5b054628..6b24bbf7 100644
--- a/test/unittest/sdt/tst.args.d
+++ b/test/unittest/sdt/tst.args.d
@@ -1,12 +1,10 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2022, 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.
  */
 
-/* @@runtest-opts: -C */
-
 #pragma D option destructive
 #pragma D option quiet
 
@@ -26,74 +24,15 @@ BEGIN
  *	pid_t	pid
  *	char	oldcomm[16]
  *	char	newcomm[16]
- *	short	omm_score_adj
- *
- * Arguments are passed as 64-bit values in arg0 through arg9, so they need
- * to be decoded into their respective values to correspond to the typed data
- * shown above.
- *
- * For LSB host byte order (x86_64) we have:
- *
- *	+-------+-------+-------+-------+-------+-------+-------+-------+
- * arg0 | o[3]  | o[2]  | o[1]  | o[0]  |  pid  |  pid  |  pid  |  pid  |
- *	+-------+-------+-------+-------+-------+-------+-------+-------+
- * arg1 | o[11] | o[10] | o[9]  | o[8]  | o[7]  | o[6]  | o[5]  | o[4]  |
- *	+-------+-------+-------+-------+-------+-------+-------+-------+
- * arg2 | n[3]  | n[2]  | n[1]  | n[0]  | o[15] | o[14] | o[13] | o[12] |
- *	+-------+-------+-------+-------+-------+-------+-------+-------+
- * arg3 | n[11] | n[10] | n[9]  | n[8]  | n[7]  | n[6]  | n[5]  | n[4]  |
- *	+-------+-------+-------+-------+-------+-------+-------+-------+
- * arg4 |   -   |   -   | adj   | adj   | n[15] | n[14] | n[13] | n[12] |
- *	+-------+-------+-------+-------+-------+-------+-------+-------+
+ *	short	oom_score_adj
  */
 this char v;
 this bool done;
 
 sdt:task::task_rename
-/(int)arg0 == pid/
+/args[0] == pid/
 {
-#define putchar(c)	this->v = (c); \
-			this->v = this->done ? 0 : this->v; \
-			this->done = !this->v; \
-			printf("%c",  this->v);
-
-	printf("PID OK, oldcomm ");
-	this->done = 0;
-	putchar(arg0 >> 32);
-	putchar(arg0 >> 40);
-	putchar(arg0 >> 48);
-	putchar(arg0 >> 56);
-	putchar(arg1);
-	putchar(arg1 >> 8);
-	putchar(arg1 >> 16);
-	putchar(arg1 >> 24);
-	putchar(arg1 >> 32);
-	putchar(arg1 >> 40);
-	putchar(arg1 >> 48);
-	putchar(arg1 >> 56);
-	putchar(arg2);
-	putchar(arg2 >> 8);
-	putchar(arg2 >> 16);
-	putchar(arg2 >> 24);
-	printf(", newcomm ");
-	this->done = 0;
-	putchar(arg2 >> 32);
-	putchar(arg2 >> 40);
-	putchar(arg2 >> 48);
-	putchar(arg2 >> 56);
-	putchar(arg3);
-	putchar(arg3 >> 8);
-	putchar(arg3 >> 16);
-	putchar(arg3 >> 24);
-	putchar(arg3 >> 32);
-	putchar(arg3 >> 40);
-	putchar(arg3 >> 48);
-	putchar(arg3 >> 56);
-	putchar(arg4);
-	putchar(arg4 >> 8);
-	putchar(arg4 >> 16);
-	putchar(arg4 >> 24);
-	printf(", oom_score_adj %hd\n", (short)arg4 >> 48);
+	printf("PID OK, oldcomm [%s], newcomm [%s], oom_score_adj %hd\n", stringof(args[1]), stringof(args[2]), args[3]);
 	exit(0);
 }
 
diff --git a/test/unittest/sdt/tst.args.r b/test/unittest/sdt/tst.args.r
index ddec9913cd1ea9697fe72b1b23386829b078cc9f..52854c0b35cc9cf865f0c16b08ffcf5c2c85509e 100644
GIT binary patch
literal 57
zcmWIWbW!m4)=|jMNlDJn%~gm_DJe=!PL0)3$V)AUh!kf4dHMOd at x{scMXB+LDOm~z
GTwDMvxDyiq

literal 77
zcmWIWbW!m4)=|jMNlDJn%~eP#DN0OEWq<=6g}l^quuO3VToB9v>dDWIFHX)cN{vrU
K$x<-j;sOB6ED at ss

diff --git a/test/unittest/variables/bvar/tst.args-match-argN.d b/test/unittest/variables/bvar/tst.args-match-argN.d
new file mode 100644
index 00000000..26d1e818
--- /dev/null
+++ b/test/unittest/variables/bvar/tst.args-match-argN.d
@@ -0,0 +1,26 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2022, 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.
+ */
+
+/*
+ * ASSERTION: When no argument mapping is in place, args[N] == argN, modulo
+ *	      datatype.
+ *
+ * SECTION: Variables/Built-in Variables/args
+ */
+
+#pragma D option quiet
+
+write:entry {
+	printf("%x vs %x\n", args[0], arg0);
+	printf("%x vs %x\n", (uint64_t)args[1], arg1);
+	printf("%x vs %x\n", args[2], arg2);
+	exit(args[0] == arg0 && (uint64_t)args[1] == arg1 && args[2] == arg2 ? 0 : 1);
+}
+
+ERROR {
+	exit(1);
+}
-- 
2.34.1




More information about the DTrace-devel mailing list