[DTrace-devel] [PATCH 4/6] test: Add a USDT "deferred" test trigger

eugene.loh at oracle.com eugene.loh at oracle.com
Sat Sep 28 02:21:56 UTC 2024


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

After a dtrace session has started, it is possible for new USDT
processes to start and for there to be a delay before dtprobed
and then dtrace becomes aware of the new process.

Add a test trigger with USDT probes that waits for dtrace to
discover it and send it USR1.  Once the USR1 is received, a
short workload is run to completion.

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
 test/triggers/Build                      |  5 +-
 test/triggers/usdt-tst-defer-prov.d      | 11 ++++
 test/triggers/usdt-tst-defer.c           | 79 ++++++++++++++++++++++++
 test/unittest/usdt/tst.defer-nodtrace.r  |  1 +
 test/unittest/usdt/tst.defer-nodtrace.sh | 49 +++++++++++++++
 5 files changed, 144 insertions(+), 1 deletion(-)
 create mode 100644 test/triggers/usdt-tst-defer-prov.d
 create mode 100644 test/triggers/usdt-tst-defer.c
 create mode 100644 test/unittest/usdt/tst.defer-nodtrace.r
 create mode 100755 test/unittest/usdt/tst.defer-nodtrace.sh

diff --git a/test/triggers/Build b/test/triggers/Build
index db80b30ed..107b3b4d1 100644
--- a/test/triggers/Build
+++ b/test/triggers/Build
@@ -13,7 +13,7 @@ EXTERNAL_64BIT_TRIGGERS = testprobe readwholedir mmap bogus-ioctl open delaydie
     ustack-tst-spin ustack-tst-mtspin \
     visible-constructor visible-constructor-static visible-constructor-static-unstripped
 
-EXTERNAL_64BIT_SDT_TRIGGERS = usdt-tst-argmap usdt-tst-args usdt-tst-forker usdt-tst-special
+EXTERNAL_64BIT_SDT_TRIGGERS = usdt-tst-argmap usdt-tst-args usdt-tst-forker usdt-tst-defer usdt-tst-special
 EXTERNAL_64BIT_TRIGGERS += $(EXTERNAL_64BIT_SDT_TRIGGERS)
 
 EXTERNAL_32BIT_TRIGGERS := visible-constructor-32
@@ -203,6 +203,9 @@ usdt-tst-args_PROV := usdt-tst-args-prov.d
 # usdt-tst-forker calls USDT probes based on dtrace -h
 usdt-tst-forker_PROV := usdt-tst-forker-prov.d
 
+# usdt-tst-defer calls USDT probes based on dtrace -h
+usdt-tst-defer_PROV := usdt-tst-defer-prov.d
+
 # usdt-tst-special calls USDT probes based on dtrace -h
 usdt-tst-special_CFLAGS := -fno-inline -O2
 usdt-tst-special_PROV := usdt-tst-special-prov.d
diff --git a/test/triggers/usdt-tst-defer-prov.d b/test/triggers/usdt-tst-defer-prov.d
new file mode 100644
index 000000000..a4ef8323d
--- /dev/null
+++ b/test/triggers/usdt-tst-defer-prov.d
@@ -0,0 +1,11 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2024, 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.
+ */
+
+provider testprov {
+	probe foo();
+	probe bar(int, int, int);
+};
diff --git a/test/triggers/usdt-tst-defer.c b/test/triggers/usdt-tst-defer.c
new file mode 100644
index 000000000..2df5401b2
--- /dev/null
+++ b/test/triggers/usdt-tst-defer.c
@@ -0,0 +1,79 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2024, 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.
+ */
+
+/*
+ * The main characteristic of this trigger code is that it allows deferred
+ * DTrace detection of the trigger.  That is, the trigger spins in "phase 1",
+ * waiting for DTrace to detect it and send it USR1.  Only then does "phase 2"
+ * run a short workload to completion.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+#include "usdt-tst-defer-prov.h"
+
+static int phase = 1;
+
+static void
+interrupt(int sig)
+{
+	phase = 2;
+}
+
+int
+main(int argc, char **argv)
+{
+	struct sigaction act;
+	int i;
+	int nphase1 = 0, nphase1foo = 0, nphase1bar = 0;
+	int nphase2 = 0, nphase2foo = 0, nphase2bar = 0;
+
+	/* set the handler to listen for SIGUSR1 */
+	act.sa_handler = interrupt;
+	act.sa_flags = 0;
+	if (sigaction(SIGUSR1, &act, NULL)) {
+		printf("set handler failed\n");
+		return 1;
+	}
+
+	/* in phase 1, loop on probe "foo" to wait on USR1 */
+	while (phase == 1) {
+		nphase1++;
+		if (TESTPROV_FOO_ENABLED()) {
+			nphase1foo++;
+			phase = 2;
+		}
+		if (TESTPROV_BAR_ENABLED()) {
+			nphase1bar++;
+			phase = 2;
+		}
+		TESTPROV_FOO();
+	}
+
+	/* wait for probes to get set up */
+	usleep(100000);
+
+	/* in phase 2, just loop over probe "bar" a fixed number of times */
+	for (i = 0; i < 10; i++) {
+		nphase2++;
+		usleep(2000);
+		if (TESTPROV_FOO_ENABLED())
+			nphase2foo++;
+		usleep(2000);
+		if (TESTPROV_BAR_ENABLED())
+			nphase2bar++;
+		usleep(2000);
+		TESTPROV_BAR(i, i + 2, i * 2);
+	}
+
+	printf("%d: %d %d %d %d %d %d\n", getpid(),
+	    nphase1, nphase1foo, nphase1bar, nphase2, nphase2foo, nphase2bar);
+
+	return 0;
+}
diff --git a/test/unittest/usdt/tst.defer-nodtrace.r b/test/unittest/usdt/tst.defer-nodtrace.r
new file mode 100644
index 000000000..2e9ba477f
--- /dev/null
+++ b/test/unittest/usdt/tst.defer-nodtrace.r
@@ -0,0 +1 @@
+success
diff --git a/test/unittest/usdt/tst.defer-nodtrace.sh b/test/unittest/usdt/tst.defer-nodtrace.sh
new file mode 100755
index 000000000..e5fd2855c
--- /dev/null
+++ b/test/unittest/usdt/tst.defer-nodtrace.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+#
+# Oracle Linux DTrace.
+# Copyright (c) 2024, 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.
+#
+# There are various tests that use the usdt-tst-defer trigger.  As a
+# baseline, let us run the trigger without enabling any USDT probes
+# and check that the counts are as expected.
+
+dtrace=$1
+trigger=`pwd`/test/triggers/usdt-tst-defer
+
+# Set up test directory.
+
+DIRNAME=$tmpdir/defer-nodtrace.$$.$RANDOM
+mkdir -p $DIRNAME
+cd $DIRNAME
+
+# Make a private copy of the trigger executable so that we get our
+# own DOF stash.
+
+cp $trigger main
+
+# Check that the is-enabled probes are false when the USDT probes are not enabled.
+# That is, nphase1foo == nphase1bar == nphase2foo == nphase2bar == 0.
+# Also, nphase2 == 10.
+# Note that nphase1 will be undefined.
+
+./main > main.out &
+pid=$!
+sleep 1
+kill -USR1 $pid
+wait
+
+echo "$pid: undefined 0 0 10 0 0" > main.out.expected
+if ! awk '{ $2 = "undefined"; print }' main.out | diff -q - main.out.expected; then
+	echo program output looks wrong for the no-DTrace case
+	echo === got ===
+	cat main.out
+	echo === expected ===
+	cat main.out.expected
+	exit 1
+fi
+
+echo success
+
+exit 0
-- 
2.43.5




More information about the DTrace-devel mailing list