[DTrace-devel] [PATCH 3/4] Fix fbt:::return and pid:::return arg1

eugene.loh at oracle.com eugene.loh at oracle.com
Wed May 4 05:01:43 UTC 2022


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

Also, remove the unused PT_REGS_BPF_*().

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
 libdtrace/dt_cg.c                            |  8 ++-
 libdtrace/dt_cg.h                            |  2 +-
 libdtrace/dt_prov_fbt.c                      |  9 ++-
 libdtrace/dt_prov_pid.c                      |  6 +-
 libdtrace/dt_pt_regs.h                       | 25 +------
 test/unittest/fbtprovider/tst.return0.d      |  6 +-
 test/unittest/fbtprovider/tst.return_arg1.sh | 70 ++++++++++++++++++++
 test/unittest/pid/tst.ret1.d                 |  3 +-
 test/unittest/pid/tst.ret2.d                 |  3 +-
 9 files changed, 95 insertions(+), 37 deletions(-)
 create mode 100755 test/unittest/fbtprovider/tst.return_arg1.sh

diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index 3c97a6c9..4a41c981 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -266,20 +266,22 @@ dt_cg_tramp_copy_regs(dt_pcb_t *pcb, int rp)
 }
 
 /*
- * Copy arguments from a dt_pt_regs structure referenced by the 'rp' argument.
+ * Copy arguments for entry probes.
+ *
+ * A dt_pt_regs structure is referenced by the 'rp' argument.
  *
  * The caller must ensure that %r7 contains the value set by the
  * dt_cg_tramp_prologue*() functions.
  */
 void
-dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp)
+dt_cg_tramp_copy_entry_args(dt_pcb_t *pcb, int rp)
 {
 	dt_irlist_t	*dlp = &pcb->pcb_ir;
 	int		i, bpf_probe_read_func_id;
 
 	/*
 	 *	for (i = 0; i < PT_REGS_ARGC; i++)
-	 *		dctx->mst->argv[i] = PT_REGS_BPF_ARGi((dt_pt_regs *)rp);
+	 *		dctx->mst->argv[i] = PT_REGS_ARGi((dt_pt_regs *)rp);
 	 *				// lddw %r0, [%rp + PT_REGS_ARGi]
 	 *				// stdw [%r7 + DMST_ARG(i)], %r0
 	 */
diff --git a/libdtrace/dt_cg.h b/libdtrace/dt_cg.h
index 5752151b..57282b0b 100644
--- a/libdtrace/dt_cg.h
+++ b/libdtrace/dt_cg.h
@@ -24,7 +24,7 @@ extern void dt_cg_tramp_prologue_act(dt_pcb_t *pcb, dt_activity_t act);
 extern void dt_cg_tramp_prologue(dt_pcb_t *pcb);
 extern void dt_cg_tramp_clear_regs(dt_pcb_t *pcb);
 extern void dt_cg_tramp_copy_regs(dt_pcb_t *pcb, int rp);
-extern void dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp);
+extern void dt_cg_tramp_copy_entry_args(dt_pcb_t *pcb, int rp);
 extern void dt_cg_tramp_call_clauses(dt_pcb_t *pcb, const dt_probe_t *prp,
 				     dt_activity_t act);
 extern void dt_cg_tramp_return(dt_pcb_t *pcb);
diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
index 62fea51e..88638bc6 100644
--- a/libdtrace/dt_prov_fbt.c
+++ b/libdtrace/dt_prov_fbt.c
@@ -167,9 +167,14 @@ static void trampoline(dt_pcb_t *pcb)
 	 *				//     (%r7 = dctx->mst)
 	 *				//     (%r8 = dctx->ctx)
 	 */
-
 	dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
-	dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
+	if (strcmp(pcb->pcb_probe->desc->prb, "return") == 0) {
+		dt_irlist_t *dlp = &pcb->pcb_ir;
+
+		emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_RET));
+		emit(dlp,  BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(1), BPF_REG_0));
+	} else
+		dt_cg_tramp_copy_entry_args(pcb, BPF_REG_8);
 	dt_cg_tramp_epilogue(pcb);
 }
 
diff --git a/libdtrace/dt_prov_pid.c b/libdtrace/dt_prov_pid.c
index af894f79..725e8cde 100644
--- a/libdtrace/dt_prov_pid.c
+++ b/libdtrace/dt_prov_pid.c
@@ -211,7 +211,11 @@ static void trampoline(dt_pcb_t *pcb)
 	 */
 
 	dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
-	dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
+	if (strcmp(pcb->pcb_probe->desc->prb, "return") == 0) {
+		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_RET));
+		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(1), BPF_REG_0));
+	} else
+		dt_cg_tramp_copy_entry_args(pcb, BPF_REG_8);
 
 	/*
 	 * Retrieve the PID of the process that caused the probe to fire.
diff --git a/libdtrace/dt_pt_regs.h b/libdtrace/dt_pt_regs.h
index 5f851573..057f1fdb 100644
--- a/libdtrace/dt_pt_regs.h
+++ b/libdtrace/dt_pt_regs.h
@@ -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.
  */
@@ -19,7 +19,7 @@ extern "C" {
 
 #if defined(__amd64)
 typedef struct pt_regs		dt_pt_regs;
-
+# define PT_REGS_RET		offsetof(dt_pt_regs, rax)
 # define PT_REGS_ARG0		offsetof(dt_pt_regs, rdi)
 # define PT_REGS_ARG1		offsetof(dt_pt_regs, rsi)
 # define PT_REGS_ARG2		offsetof(dt_pt_regs, rdx)
@@ -30,17 +30,9 @@ typedef struct pt_regs		dt_pt_regs;
 # define PT_REGS_ARGSTKBASE	1
 # define PT_REGS_IP		offsetof(dt_pt_regs, rip)
 # define PT_REGS_SP		offsetof(dt_pt_regs, rsp)
-
-# define PT_REGS_BPF_ARG0(r)	((r)->rdi)
-# define PT_REGS_BPF_ARG1(r)	((r)->rsi)
-# define PT_REGS_BPF_ARG2(r)	((r)->rdx)
-# define PT_REGS_BPF_ARG3(r)	((r)->rcx)
-# define PT_REGS_BPF_ARG4(r)	((r)->r8)
-# define PT_REGS_BPF_ARG5(r)	((r)->r9)
-# define PT_REGS_BPF_IP(r)	((r)->rip)
-# define PT_REGS_BPF_SP(r)	((r)->rsp)
 #elif defined(__aarch64__)
 typedef struct user_pt_regs	dt_pt_regs;
+# define PT_REGS_RET		offsetof(dt_pt_regs, regs[0])
 # define PT_REGS_ARG0		offsetof(dt_pt_regs, regs[0])
 # define PT_REGS_ARG1		offsetof(dt_pt_regs, regs[1])
 # define PT_REGS_ARG2		offsetof(dt_pt_regs, regs[2])
@@ -53,17 +45,6 @@ typedef struct user_pt_regs	dt_pt_regs;
 # define PT_REGS_ARGSTKBASE	0
 # define PT_REGS_IP		offsetof(dt_pt_regs, pc)
 # define PT_REGS_SP		offsetof(dt_pt_regs, sp)
-
-# define PT_REGS_BPF_ARG0(r)	((r)->regs[0])
-# define PT_REGS_BPF_ARG1(r)	((r)->regs[1])
-# define PT_REGS_BPF_ARG2(r)	((r)->regs[2])
-# define PT_REGS_BPF_ARG3(r)	((r)->regs[3])
-# define PT_REGS_BPF_ARG4(r)	((r)->regs[4])
-# define PT_REGS_BPF_ARG5(r)	((r)->regs[5])
-# define PT_REGS_BPF_ARG6(r)	((r)->regs[6])
-# define PT_REGS_BPF_ARG7(r)	((r)->regs[7])
-# define PT_REGS_BPF_IP(r)	((r)->pc)
-# define PT_REGS_BPF_SP(r)	((r)->sp)
 #else
 # error ISA not supported
 #endif
diff --git a/test/unittest/fbtprovider/tst.return0.d b/test/unittest/fbtprovider/tst.return0.d
index 3d58e84f..0b7091b3 100644
--- a/test/unittest/fbtprovider/tst.return0.d
+++ b/test/unittest/fbtprovider/tst.return0.d
@@ -1,18 +1,16 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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: simple fbt provider arg0 and probfunc print test.
+ * ASSERTION: simple fbt provider arg0 and probefunc print test.
  *
  * SECTION: FBT Provider/Probe arguments
  */
 
-/* @@runtest-opts: -Z */
-
 #pragma D option quiet
 #pragma D option statusrate=10ms
 
diff --git a/test/unittest/fbtprovider/tst.return_arg1.sh b/test/unittest/fbtprovider/tst.return_arg1.sh
new file mode 100755
index 00000000..bb8342a8
--- /dev/null
+++ b/test/unittest/fbtprovider/tst.return_arg1.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+#
+# 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.
+
+dtrace=$1
+
+DIRNAME="$tmpdir/fbt.return_arg1.$$.$RANDOM"
+mkdir -p $DIRNAME
+cd $DIRNAME
+
+cat << EOF > main.c
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#define N 7
+int main(int c, char **v) {
+	int i, fds[N];
+	for (i = 0; i < N; i++)
+		printf("%d\n", fds[i] = open("/dev/zero", O_RDONLY));
+	for (; i--; )
+		close(fds[i]);
+	return 0;
+}
+EOF
+
+/usr/bin/gcc main.c
+if [ $? -ne 0 ]; then
+	echo "compilation failure"
+	exit 1
+fi
+
+$dtrace $dt_flags -c ./a.out -o out.D -qZn '
+fbt:vmlinux:do_sys_open*:return
+/pid == $target/
+{
+	printf("%d\n", arg1);
+}' > out.C 2>&1
+
+if [ $? -ne 0 ]; then
+	echo "DTrace failure"
+	cat out.C
+	cat out.D
+	exit 1
+fi
+
+# multiple fbt::do_sys_open*:return probes might fire per open()
+if [ `awk 'NF' out.D | uniq -c | awk '{print $1}' | uniq | wc -1` -ne 1 ]; then
+	echo "inconsistent numbers of probes firing"
+	cat out.C
+	cat out.D
+	exit 1
+fi
+
+awk 'NF' out.D | uniq > out.cmp
+diff -q out.cmp out.C
+
+if [ $? -ne 0 ]; then
+	echo "diff failure"
+	cat out.C
+	cat out.D
+	diff out.cmp out.C
+	exit 1
+fi
+
+exit 0
diff --git a/test/unittest/pid/tst.ret1.d b/test/unittest/pid/tst.ret1.d
index bdf7d274..398e2cc8 100644
--- a/test/unittest/pid/tst.ret1.d
+++ b/test/unittest/pid/tst.ret1.d
@@ -1,10 +1,9 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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.
  */
-/* @@xfail: dtv2 */
 /* @@runtest-opts: $_pid */
 /* @@trigger: pid-tst-ret1 */
 /* @@trigger-timing: before */
diff --git a/test/unittest/pid/tst.ret2.d b/test/unittest/pid/tst.ret2.d
index d3d482e3..a542646a 100644
--- a/test/unittest/pid/tst.ret2.d
+++ b/test/unittest/pid/tst.ret2.d
@@ -1,10 +1,9 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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.
  */
-/* @@xfail: dtv2 */
 /* @@runtest-opts: $_pid */
 /* @@trigger: pid-tst-ret2 */
 /* @@trigger-timing: before */
-- 
2.18.4




More information about the DTrace-devel mailing list