From: Eugene Loh <[email protected]>
If a clause includes a destructive action but -w is not used, dtrace
should not start up, even if the clause is ignored (due to -Z).
Solaris treated this as a runtime error. We should do the same.
The test err.Z_no-w.sh was misguided and is replaced by a more
direct test.
Signed-off-by: Eugene Loh <[email protected]>
Reviewed-by: Nick Alcock <[email protected]>
---
libdtrace/dt_bpf.c | 15 ++--
libdtrace/dt_cg.c | 1 +
libdtrace/dt_impl.h | 1 +
.../options/err.no-w-or-destructive2.d | 26 +++++++
.../options/err.no-w-or-destructive2.r | 3 +
test/unittest/usdt/err.Z_no-w.r | 4 -
test/unittest/usdt/err.Z_no-w.sh | 76 -------------------
7 files changed, 40 insertions(+), 86 deletions(-)
create mode 100644 test/unittest/options/err.no-w-or-destructive2.d
create mode 100644 test/unittest/options/err.no-w-or-destructive2.r
delete mode 100644 test/unittest/usdt/err.Z_no-w.r
delete mode 100755 test/unittest/usdt/err.Z_no-w.sh
diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
index cbf59c1d9..8b617d65e 100644
--- a/libdtrace/dt_bpf.c
+++ b/libdtrace/dt_bpf.c
@@ -1343,6 +1343,15 @@ dt_bpf_load_progs(dtrace_hdl_t *dtp, uint_t cflags)
*/
dtrace_getopt(dtp, "destructive", &dest_ok);
+ /*
+ * If we have any destructive actions at all and -w is not set,
+ * error out. Solaris would reject this as a runtime error. So,
+ * although we could have detected this problem at compilation,
+ * we mimic Solaris and wait until now to report.
+ */
+ if (dtp->dt_destructive && dest_ok == DTRACEOPT_UNSET)
+ return dt_set_errno(dtp, EDT_DESTRUCTIVE);
+
dp = NULL;
for (prp = dt_list_next(&dtp->dt_enablings); prp != NULL;
prp = dt_list_next(prp)) {
@@ -1362,12 +1371,6 @@ dt_bpf_load_progs(dtrace_hdl_t *dtp, uint_t cflags)
DT_DISASM_PROG_LINKED(dtp, cflags, dp, stderr, NULL, prp->desc);
- if (dp->dtdo_flags & DIFOFLG_DESTRUCTIVE &&
- dest_ok == DTRACEOPT_UNSET) {
- dt_set_errno(dtp, EDT_DESTRUCTIVE);
- goto fail;
- }
-
fd = dt_bpf_load_prog(dtp, prp, dp, cflags);
if (fd == -1)
goto fail;
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index a1eff8efe..0593a497a 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -1876,6 +1876,7 @@ dt_cg_clsflags(dt_pcb_t *pcb, dtrace_actkind_t kind, const dt_node_t *dnp)
if (DTRACEACT_ISDESTRUCTIVE(kind)) {
*cfp |= DT_CLSFLAG_DESTRUCT;
+ pcb->pcb_hdl->dt_destructive |= 1;
if (kind == DTRACEACT_RETURN)
*cfp |= DT_CLSFLAG_RETURN;
diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index bf4f6c7bd..7300af6ad 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -367,6 +367,7 @@ struct dtrace_hdl {
char *dt_sysslice; /* the systemd system slice: set via -xsysslice */
uint_t dt_lazyload; /* boolean: set via -xlazyload */
uint_t dt_droptags; /* boolean: set via -xdroptags */
+ uint_t dt_destructive; /* have any destructive actions */
uint_t dt_active; /* boolean: set once tracing is active */
uint_t dt_stopped; /* boolean: set once tracing is stopped */
processorid_t dt_beganon; /* CPU that executed BEGIN probe (if any) */
diff --git a/test/unittest/options/err.no-w-or-destructive2.d b/test/unittest/options/err.no-w-or-destructive2.d
new file mode 100644
index 000000000..c0a8486c2
--- /dev/null
+++ b/test/unittest/options/err.no-w-or-destructive2.d
@@ -0,0 +1,26 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2025, 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: Without -w or -xdestructive, destructive operations are not ok,
+ * even if a clause will be ignored (since the associated probe
+ * does not exist at the point of initial program construction
+ * and loading).
+ *
+ * SECTION: Options and Tunables/Consumer Options
+ */
+/* @@runtest-opts: -Z */
+
+BEGIN
+{
+ exit(0);
+}
+
+bogus:bogus:bogus:bogus
+{
+ system("echo ok");
+}
diff --git a/test/unittest/options/err.no-w-or-destructive2.r b/test/unittest/options/err.no-w-or-destructive2.r
new file mode 100644
index 000000000..1a6959475
--- /dev/null
+++ b/test/unittest/options/err.no-w-or-destructive2.r
@@ -0,0 +1,3 @@
+-- @@stderr --
+dtrace: script 'test/unittest/options/err.no-w-or-destructive2.d' matched 1 probe
+dtrace: could not enable tracing: Destructive actions not allowed
diff --git a/test/unittest/usdt/err.Z_no-w.r b/test/unittest/usdt/err.Z_no-w.r
deleted file mode 100644
index b81622481..000000000
--- a/test/unittest/usdt/err.Z_no-w.r
+++ /dev/null
@@ -1,4 +0,0 @@
-dtrace is running so start the trigger
-dtrace died as expected after trigger started
--- @@stderr --
-dtrace: processing aborted: Destructive actions not allowed
diff --git a/test/unittest/usdt/err.Z_no-w.sh b/test/unittest/usdt/err.Z_no-w.sh
deleted file mode 100755
index 4f129341d..000000000
--- a/test/unittest/usdt/err.Z_no-w.sh
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/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.
-#
-# This test verifies that dtrace will not run a destructive script
-# for USDT probes if -w is not specified.
-#
-# Specifically, the script is launched with -Z and no USDT processes are
-# initially present. Only once a USDT process is detected does dtrace
-# fail due to the destructive action.
-
-dtrace=$1
-trigger=`pwd`/test/triggers/usdt-tst-defer
-
-# Set up test directory.
-
-DIRNAME=$tmpdir/Z_no-w.$$.$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
-
-# Run dtrace.
-
-$dtrace $dt_flags -Zq -o dtrace.out -n '
-testprov*:::foo
-{
- raise(SIGUSR1);
-}' &
-dtpid=$!
-
-# Wait up to half of the timeout period for dtrace to start up.
-
-iter=$((timeout / 2))
-while [ $iter -gt 0 ]; do
- sleep 1
- if [ -e dtrace.out ]; then
- break
- fi
- iter=$((iter - 1))
-done
-if [[ $iter -eq 0 ]]; then
- echo ERROR starting DTrace job
- cat dtrace.out
- exit 1
-fi
-
-# Start a trigger process.
-
-echo dtrace is running so start the trigger
-./main > main.out &
-pid=$!
-
-# Check again if dtrace is still running.
-
-sleep 2
-if [[ ! -d /proc/$dtpid ]]; then
- echo dtrace died as expected after trigger started
-else
- echo dtrace is unexpectedly still running
- kill -9 $dtpid
- wait $dtpid
-fi
-
-# Tell the trigger to proceed to completion.
-
-kill -USR1 $pid
-wait $pid
-
-exit 1
--
2.43.5
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.