[DTrace-devel] [PATCH 2/4] Fix syscall:::return args

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


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

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
 libdtrace/dt_prov_syscall.c              | 30 +++++++----
 test/unittest/syscall/tst.return_args.sh | 65 ++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 9 deletions(-)
 create mode 100755 test/unittest/syscall/tst.return_args.sh

diff --git a/libdtrace/dt_prov_syscall.c b/libdtrace/dt_prov_syscall.c
index 2c6644d4..a2e105eb 100644
--- a/libdtrace/dt_prov_syscall.c
+++ b/libdtrace/dt_prov_syscall.c
@@ -159,19 +159,31 @@ static void trampoline(dt_pcb_t *pcb)
 	dt_cg_tramp_clear_regs(pcb);
 
 	/*
-	 *	for (i = 0; i < argc; i++)
-	 *		dctx->mst->argv[i] =
-	 *			((struct syscall_data *)dctx->ctx)->arg[i];
-	 *				// lddw %r0, [%r8 + SCD_ARG(i)]
-	 *				// stdw [%r7 + DMST_ARG(i)], %r0
+	 * Copy in the probe args.
 	 */
-	for (i = 0; i < pcb->pcb_probe->argc; i++) {
-		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, SCD_ARG(i)));
-		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(i), BPF_REG_0));
+	if (strcmp(pcb->pcb_probe->desc->prb, "return") == 0) {
+		/* the return value must be in both arg0 and arg1 */
+		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, SCD_ARG(0)));
+		for (i = 0; i < 2; i++)
+			emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(i), BPF_REG_0));
+	} else {
+		/*
+		 *	for (i = 0; i < argc; i++)
+		 *		dctx->mst->argv[i] =
+		 *			((struct syscall_data *)dctx->ctx)->arg[i];
+		 *				// lddw %r0, [%r8 + SCD_ARG(i)]
+		 *				// stdw [%r7 + DMST_ARG(i)], %r0
+		 */
+		for (i = 0; i < pcb->pcb_probe->argc; i++) {
+			emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, SCD_ARG(i)));
+			emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(i), BPF_REG_0));
+		}
 	}
 
 	/*
-	 *	for i = argc; i < ARRAY_SIZE(((dt_mstate_t *)0)->argv); i++)
+	 * Zero the remaining probe args.
+	 *
+	 *	for ( ; i < ARRAY_SIZE(((dt_mstate_t *)0)->argv); i++)
 	 *		dctx->mst->argv[i] = 0;
 	 *				// stdw [%r7 + DMST_ARG(i)], 0
 	 */
diff --git a/test/unittest/syscall/tst.return_args.sh b/test/unittest/syscall/tst.return_args.sh
new file mode 100755
index 00000000..14956598
--- /dev/null
+++ b/test/unittest/syscall/tst.return_args.sh
@@ -0,0 +1,65 @@
+#!/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/syscall.return_args.$$.$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 '
+syscall::open:return,
+syscall::openat:return
+/pid == $target/
+{
+	printf("%d\t%d\n", arg0, arg1);
+}' > out.C 2>&1
+
+if [ $? -ne 0 ]; then
+	echo "DTrace failure"
+	cat out.C
+	cat out.D
+	exit 1
+fi
+
+paste out.C out.C > out.cmp
+echo >> out.cmp
+diff -q out.D out.cmp
+
+if [ $? -ne 0 ]; then
+	echo "diff failure"
+	cat out.C
+	cat out.cmp
+	cat out.D
+	diff out.D out.cmp
+	exit 1
+fi
+
+exit 0
-- 
2.18.4




More information about the DTrace-devel mailing list