[DTrace-devel] [PATCH v2 19/19] test: Add another USDT open/close test

eugene.loh at oracle.com eugene.loh at oracle.com
Thu Oct 24 17:21:43 UTC 2024


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

There is already a test to check that "dtrace -l" sees USDT
probes come and go as an executable loads and unloads a shared
library with USDT probes.  (See dlclose1.sh.)  But it could
also fail if DTrace does not immediately notice USDT probes
coming or going.

Introduce a test that allows a grace period before DTrace
notices a USDT probe come or go.

There is a deadlib.so here.  It is not needed for the test.
It simply mimics other, similar tests.  The real thing to do
might be to put these shared libraries, common to multiple
tests, in test/triggers.

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
 test/unittest/usdt/tst.dlclose4.r  |   5 +
 test/unittest/usdt/tst.dlclose4.sh | 210 +++++++++++++++++++++++++++++
 2 files changed, 215 insertions(+)
 create mode 100644 test/unittest/usdt/tst.dlclose4.r
 create mode 100755 test/unittest/usdt/tst.dlclose4.sh

diff --git a/test/unittest/usdt/tst.dlclose4.r b/test/unittest/usdt/tst.dlclose4.r
new file mode 100644
index 000000000..07927a4a4
--- /dev/null
+++ b/test/unittest/usdt/tst.dlclose4.r
@@ -0,0 +1,5 @@
+as expected: USDT probe appeared
+as expected: USDT probe disappeared
+as expected: USDT probe appeared
+as expected: USDT probe disappeared
+success
diff --git a/test/unittest/usdt/tst.dlclose4.sh b/test/unittest/usdt/tst.dlclose4.sh
new file mode 100755
index 000000000..eaf4905ce
--- /dev/null
+++ b/test/unittest/usdt/tst.dlclose4.sh
@@ -0,0 +1,210 @@
+#!/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.
+#
+PATH=/usr/bin:/usr/sbin:$PATH
+
+#
+# In this test, we send alternating USR1 and USR2 signals to an executable
+# that responds by opening and closing, respectively, a shared library with
+# USDT probes.  After each signal, we check "dtrace -l" to confirm that the
+# USDT probes are and are not listed, as expected.
+#
+
+dtrace=$1
+CC=/usr/bin/gcc
+CFLAGS=
+
+DIRNAME="$tmpdir/usdt-dlclose4.$$.$RANDOM"
+mkdir -p $DIRNAME
+cd $DIRNAME
+
+#
+# Set up the source files.
+#
+
+cat > Makefile <<EOF
+all: main livelib.so
+
+main: main.o prov.o
+	\$(CC) -o main main.o -ldl
+
+main.o: main.c
+	\$(CC) -c main.c
+
+livelib.so: livelib.o prov.o
+	\$(CC) -shared -o livelib.so livelib.o prov.o -lc
+
+livelib.o: livelib.c prov.h
+	\$(CC) -c livelib.c
+
+prov.o: livelib.o prov.d
+	$dtrace -G -s prov.d livelib.o
+
+prov.h: prov.d
+	$dtrace -h -s prov.d
+
+clean:
+	rm -f main.o livelib.o prov.o prov.h
+
+clobber: clean
+	rm -f main livelib.so
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+	probe go();
+};
+EOF
+
+cat > livelib.c <<EOF
+#include "prov.h"
+
+void
+go(void)
+{
+	TEST_PROV_GO();
+}
+EOF
+
+cat > main.c <<EOF
+#include <dlfcn.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void *live;
+
+/*
+ * Open and close livelib.so, thereby adding or removing USDT probes.
+ */
+
+static void my_open(int sig) {
+	live = dlopen("./livelib.so", RTLD_LAZY | RTLD_LOCAL);
+	if (live == NULL) {
+		printf("dlopen of livelib.so failed: %s\n", dlerror());
+		exit(1);
+	}
+}
+
+static void my_close(int sig) {
+	dlclose(live);
+}
+
+int
+main(int argc, char **argv)
+{
+	struct sigaction act;
+
+	/*
+	 * Set USR1 (USR2) to open (close) the livelib.so.
+	 */
+	act.sa_flags = 0;
+	act.sa_handler = my_open;
+	if (sigaction(SIGUSR1, &act, NULL)) {
+		printf("set handler failed\n");
+		return 1;
+	}
+	act.sa_handler = my_close;
+	if (sigaction(SIGUSR2, &act, NULL)) {
+		printf("set handler failed\n");
+		return 1;
+	}
+
+	/*
+	 * Listen for signals.
+	 */
+	while (pause() == -1)
+		;
+
+	return 0;
+}
+EOF
+
+#
+# Build.
+#
+
+make > /dev/null
+if [ $? -ne 0 ]; then
+	echo "failed to build" >& 2
+	exit 1
+fi
+
+# Define a function that looks for the USDT probe with "dtrace -l".
+# For debugging, one could also check:
+#     ls /run/dtrace/probes/$pid/test_prov$pid/livelib.so/go/go 
+#     ls /run/dtrace/stash/dof-pid/$pid/*/parsed/test_prov:livelib.so:go:go 
+
+function check_USDT_probes() {
+	$dtrace -lP test_prov$pid |& awk '
+	    /ID *PROVIDER *MODULE *FUNCTION *NAME/ { next }
+	    /test_prov'$pid' *livelib\.so *go *go/ { exit(0) }
+	    /No probe matches description/ { exit(1) }'
+	return $?
+}
+
+# Define a function that checks loading the library:
+# send USR1 and wait up to 6 seconds for the USDT probe to appear.
+
+function load_lib() {
+	kill -s USR1 $pid
+	for iter in `seq 6`; do
+		sleep 1
+		if check_USDT_probes; then
+			iter=0
+			break
+		fi
+	done
+	if [[ $iter -ne 0 ]]; then
+		echo did not see USDT probe
+		kill -s KILL $pid
+		exit 1
+	fi
+	echo as expected: USDT probe appeared
+}
+
+# Define a function that checks unloading the library:
+# send USR2 and wait up to 6 seconds for the USDT probe to disappear.
+
+function unload_lib() {
+	kill -s USR2 $pid  # send USR2 to unload library and USDT probe
+	for iter in `seq 6`; do
+		sleep 1
+		if ! check_USDT_probes; then
+			iter=0
+			break
+		fi
+	done
+	if [[ $iter -ne 0 ]]; then
+		echo still see USDT probe after timeout
+		kill -s KILL $pid
+		exit 1
+	fi
+	echo as expected: USDT probe disappeared
+}
+
+# Start the process.
+
+./main &
+pid=$!
+sleep 2
+
+# Check.
+
+load_lib
+unload_lib
+load_lib
+unload_lib
+
+# Clean up.
+
+kill -s KILL $pid
+wait $pid >& /dev/null
+
+echo success
+exit 0
-- 
2.43.5




More information about the DTrace-devel mailing list