[DTrace-devel] [PATCH v6 4/6] usdt: typed args and arg mapping
Nick Alcock
nick.alcock at oracle.com
Tue Nov 5 20:59:40 UTC 2024
This change propagates the arg type and mapping info we just got into the
pid_probespec_t onward into the underlying dt_uprobe_t and shuffles the
argument values by calling dt_cg_tramp_map_args(). With this, USDT probes
should now have visible types which obey the :-notation translators
specified in their .d file (this is now tested).
The probe_info hook has been moved from the underlying probe to the
overlying one as part of this: underlying probes don't have any user-visible
args to get info for, and their probe_info functions are never called. We
populate the dt_argdesc_t in a function ultimately called from USDT probe
discovery via provide_underlying, so it predates trampoline setup let alone
probe_info on the overlying probe and all the args info is present before it
is needed.
Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
---
include/dtrace/pid.h | 1 +
libdtrace/dt_prov_uprobe.c | 184 ++++++++++++++++--
test/triggers/usdt-tst-argmap-prov.d | 5 +-
test/triggers/usdt-tst-argmap.c | 5 +-
.../dtrace-util/tst.ListProbesArgsUSDT.r | 130 +++++++++++++
.../dtrace-util/tst.ListProbesArgsUSDT.r.p | 2 +
.../dtrace-util/tst.ListProbesArgsUSDT.sh | 89 +++++++++
test/unittest/usdt/err.argmap-null.d | 41 ++++
test/unittest/usdt/err.argmap-null.r | 2 +
test/unittest/usdt/err.argmap-null.r.p | 2 +
test/unittest/usdt/tst.argmap-null.d | 32 +++
test/unittest/usdt/tst.argmap-typed-partial.d | 49 +++++
test/unittest/usdt/tst.argmap-typed.d | 48 +++++
test/unittest/usdt/tst.argmap.d | 5 +-
14 files changed, 577 insertions(+), 18 deletions(-)
create mode 100644 test/unittest/dtrace-util/tst.ListProbesArgsUSDT.r
create mode 100755 test/unittest/dtrace-util/tst.ListProbesArgsUSDT.r.p
create mode 100755 test/unittest/dtrace-util/tst.ListProbesArgsUSDT.sh
create mode 100644 test/unittest/usdt/err.argmap-null.d
create mode 100644 test/unittest/usdt/err.argmap-null.r
create mode 100755 test/unittest/usdt/err.argmap-null.r.p
create mode 100644 test/unittest/usdt/tst.argmap-null.d
create mode 100644 test/unittest/usdt/tst.argmap-typed-partial.d
create mode 100644 test/unittest/usdt/tst.argmap-typed.d
diff --git a/include/dtrace/pid.h b/include/dtrace/pid.h
index 25bfacfdbfe2..c53e600475df 100644
--- a/include/dtrace/pid.h
+++ b/include/dtrace/pid.h
@@ -22,6 +22,7 @@ typedef enum pid_probetype {
DTPPT_ENTRY,
DTPPT_RETURN,
DTPPT_OFFSETS,
+ DTPPT_USDT,
DTPPT_IS_ENABLED
} pid_probetype_t;
diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
index a8c1ab2761f0..1a1500c03ecc 100644
--- a/libdtrace/dt_prov_uprobe.c
+++ b/libdtrace/dt_prov_uprobe.c
@@ -46,9 +46,11 @@
/* Provider name for the underlying probes. */
static const char prvname[] = "uprobe";
-#define PP_IS_RETURN 1
-#define PP_IS_FUNCALL 2
-#define PP_IS_ENABLED 4
+#define PP_IS_RETURN 0x1
+#define PP_IS_FUNCALL 0x2
+#define PP_IS_ENABLED 0x4
+#define PP_IS_USDT 0x8
+#define PP_IS_MAPPED 0x10
typedef struct dt_uprobe {
dev_t dev;
@@ -57,7 +59,10 @@ typedef struct dt_uprobe {
uint64_t off;
int flags;
tp_probe_t *tp;
- dt_list_t probes; /* pid/USDT probes triggered by it */
+ int argc; /* number of args */
+ dt_argdesc_t *args; /* args array (points into argvbuf) */
+ char *argvbuf; /* arg strtab */
+ dt_list_t probes; /* pid/USDT probes triggered by it */
} dt_uprobe_t;
typedef struct list_probe {
@@ -123,6 +128,8 @@ static void probe_destroy_underlying(dtrace_hdl_t *dtp, void *datap)
dt_tp_destroy(dtp, tpp);
free_probe_list(dtp, dt_list_next(&upp->probes));
dt_free(dtp, upp->fn);
+ dt_free(dtp, upp->args);
+ dt_free(dtp, upp->argvbuf);
dt_free(dtp, upp);
}
@@ -516,6 +523,80 @@ static int discover(dtrace_hdl_t *dtp)
return 0;
}
+/*
+ * Populate args for an underlying probe for use by the overlying USDT probe.
+ * The overlying probe does not exist yet at this point, so the arg data is
+ * stored in the underlying probe instead and will be accessed when probe_info
+ * is called in the overlying probe.
+ *
+ * Move it into dt_argdesc_t's for use later on. The char *'s in that structure
+ * are pointers into the argvbuf array, which is a straight concatenated copy of
+ * the nargv/xargv in the pid_probespec_t.
+ */
+static int populate_args(dtrace_hdl_t *dtp, const pid_probespec_t *psp,
+ dt_uprobe_t *upp)
+{
+ char **nargv = NULL;
+ char *nptr = NULL, *xptr = NULL;
+ size_t i;
+
+ upp->argc = psp->pps_xargc;
+
+ /*
+ * If we have a nonzero number of args, we always have at least one narg
+ * and at least one xarg. Double-check to be sure. (These are not
+ * populated, and thus left 0/NULL, for non-USDT probes.)
+ */
+ if (upp->argc == 0 || psp->pps_xargv == NULL || psp->pps_nargv == NULL
+ || psp->pps_xargvlen == 0 || psp->pps_nargvlen == 0)
+ return 0;
+
+ upp->argvbuf = dt_alloc(dtp, psp->pps_xargvlen + psp->pps_nargvlen);
+ if(upp->argvbuf == NULL)
+ return -1;
+ memcpy(upp->argvbuf, psp->pps_xargv, psp->pps_xargvlen);
+ xptr = upp->argvbuf;
+
+ memcpy(upp->argvbuf + psp->pps_xargvlen, psp->pps_nargv, psp->pps_nargvlen);
+ nptr = upp->argvbuf + psp->pps_xargvlen;
+
+ upp->args = dt_calloc(dtp, upp->argc, sizeof(dt_argdesc_t));
+ if (upp->args == NULL)
+ return -1;
+
+ /*
+ * Construct an array to allow accessing native args by index.
+ */
+ if ((nargv = dt_calloc(dtp, psp->pps_nargc, sizeof (char *))) == NULL)
+ goto fail;
+
+ for (i = 0; i < psp->pps_nargc; i++, nptr += strlen(nptr) + 1)
+ nargv[i] = nptr;
+
+ /*
+ * Fill up the upp->args array based on xargs. If this indicates that
+ * mapping is needed, note as much.
+ */
+ for (i = 0; i < upp->argc; i++, xptr += strlen(xptr) + 1) {
+ int map_arg = psp->pps_argmap[i];
+
+ upp->args[i].native = nargv[map_arg];
+ upp->args[i].xlate = xptr;
+ upp->args[i].mapping = map_arg;
+ upp->args[i].flags = 0;
+
+ if (i != map_arg)
+ upp->flags |= PP_IS_MAPPED;
+ }
+
+ free(nargv);
+ return 0;
+
+ fail:
+ free(nargv);
+ return -1;
+}
+
/*
* Look up or create an underlying (real) probe, corresponding directly to a
* uprobe. Since multiple pid and USDT probes may all map onto the same
@@ -530,7 +611,7 @@ static dt_probe_t *create_underlying(dtrace_hdl_t *dtp,
char prb[DTRACE_NAMELEN];
dtrace_probedesc_t pd;
dt_probe_t *uprp;
- dt_uprobe_t *upp;
+ dt_uprobe_t *upp = NULL;
/*
* The underlying probes (uprobes) represent the tracepoints that pid
@@ -555,6 +636,7 @@ static dt_probe_t *create_underlying(dtrace_hdl_t *dtp,
case DTPPT_IS_ENABLED:
case DTPPT_ENTRY:
case DTPPT_OFFSETS:
+ case DTPPT_USDT:
snprintf(prb, sizeof(prb), "%lx", psp->pps_off);
break;
default:
@@ -568,6 +650,8 @@ static dt_probe_t *create_underlying(dtrace_hdl_t *dtp,
pd.fun = psp->pps_fun;
pd.prb = prb;
+ dt_dprintf("Providing underlying probe %s:%s:%s:%s @ %lx\n", psp->pps_prv,
+ psp->pps_mod, psp->pps_fn, psp->pps_prb, psp->pps_off);
uprp = dt_probe_lookup(dtp, &pd);
if (uprp == NULL) {
dt_provider_t *pvp;
@@ -591,12 +675,24 @@ static dt_probe_t *create_underlying(dtrace_hdl_t *dtp,
goto fail;
uprp = dt_probe_insert(dtp, pvp, pd.prv, pd.mod, pd.fun, pd.prb,
- upp);
+ upp);
if (uprp == NULL)
goto fail;
} else
upp = uprp->prv_data;
+ /*
+ * Only one USDT probe can correspond to each underlying probe.
+ */
+ if (psp->pps_type == DTPPT_USDT && upp->flags == PP_IS_USDT) {
+ dt_dprintf("Found overlapping USDT probe at %lx/%lx/%lx/%s\n",
+ upp->dev, upp->inum, upp->off, upp->fn);
+ goto fail;
+ }
+
+ if (populate_args(dtp, psp, upp) < 0)
+ goto fail;
+
switch (psp->pps_type) {
case DTPPT_RETURN:
upp->flags |= PP_IS_RETURN;
@@ -604,15 +700,20 @@ static dt_probe_t *create_underlying(dtrace_hdl_t *dtp,
case DTPPT_IS_ENABLED:
upp->flags |= PP_IS_ENABLED;
break;
+ case DTPPT_USDT:
+ upp->flags |= PP_IS_USDT;
+ break;
default: ;
/*
* No flags needed for other types.
*/
}
- return uprp;
+ return uprp;
fail:
+ dt_dprintf("Failed to instantiate %s:%s:%s:%s\n", psp->pps_prv,
+ psp->pps_mod, psp->pps_fn, psp->pps_prb);
probe_destroy(dtp, upp);
return NULL;
}
@@ -732,7 +833,7 @@ static int provide_pid_probe(dtrace_hdl_t *dtp, const pid_probespec_t *psp)
static int provide_usdt_probe(dtrace_hdl_t *dtp, const pid_probespec_t *psp)
{
- if (psp->pps_type != DTPPT_OFFSETS &&
+ if (psp->pps_type != DTPPT_USDT &&
psp->pps_type != DTPPT_IS_ENABLED) {
dt_dprintf("pid: unknown USDT probe type %i\n", psp->pps_type);
return -1;
@@ -786,7 +887,13 @@ static void enable_usdt(dtrace_hdl_t *dtp, dt_probe_t *prp)
* int dt_uprobe(dt_pt_regs *regs)
*
* The trampoline will first populate a dt_dctx_t struct. It will then emulate
- * the firing of all dependent pid* probes and their clauses.
+ * the firing of all dependent pid* and USDT probes and their clauses, or (in
+ * the case of is-enabled probes), do the necessary copying (is-enabled probes
+ * have no associated clauses and their behaviour is hardwired).
+ *
+ * Trampolines associated with USDT probes will also arrange for argument
+ * shuffling before the USDT clauses are invoked if the argmap array calls for
+ * it.
*/
static int trampoline(dt_pcb_t *pcb, uint_t exitlbl)
{
@@ -864,7 +971,7 @@ static int trampoline(dt_pcb_t *pcb, uint_t exitlbl)
}
/*
- * USDT
+ * USDT.
*/
/* In some cases, we know there are no USDT probes. */ // FIXME: add more checks
@@ -873,6 +980,16 @@ static int trampoline(dt_pcb_t *pcb, uint_t exitlbl)
dt_cg_tramp_copy_args_from_regs(pcb, 0);
+ /*
+ * Apply arg mappings, if needed.
+ */
+ if (upp->flags & PP_IS_MAPPED) {
+
+ /* dt_cg_tramp_map_args() works from the saved args. */
+ dt_cg_tramp_save_args(pcb);
+ dt_cg_tramp_map_args(pcb, upp->args, upp->argc);
+ }
+
/*
* Retrieve the PID of the process that caused the probe to fire.
*/
@@ -1083,10 +1200,51 @@ attach_bpf:
static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
int *argcp, dt_argdesc_t **argvp)
{
- *argcp = 0; /* no known arguments */
- *argvp = NULL;
+ size_t i = 0;
+ list_probe_t *pup = prp->prv_data;
+ dt_uprobe_t *upp;
+ size_t argc = 0;
+ dt_argdesc_t *argv = NULL;
+
+ /* No underlying probes? No args. */
+ if (!pup)
+ goto done;
+
+ upp = pup->probe->prv_data;
+ if (!upp || upp->args == NULL)
+ goto done;
+
+ argc = upp->argc;
+ argv = dt_calloc(dtp, argc, sizeof(dt_argdesc_t));
+ if (argv == NULL)
+ return dt_set_errno(dtp, EDT_NOMEM);
+
+ for (i = 0; i < argc; i++) {
+ argv[i].native = strdup(upp->args[i].native);
+ if (upp->args[i].xlate)
+ argv[i].xlate = strdup(upp->args[i].xlate);
+ argv[i].mapping = i;
+
+ if (argv[i].native == NULL ||
+ (upp->args[i].xlate != NULL && argv[i].xlate == NULL))
+ goto oom;
+ }
+
+done:
+ *argcp = argc;
+ *argvp = argv;
return 0;
+ oom:
+ size_t j;
+
+ for (j = 0; j <= i; j++) {
+ free((char *) argv[i].native);
+ free((char *) argv[i].xlate);
+ }
+
+ dt_free(dtp, argv);
+ return dt_set_errno(dtp, EDT_NOMEM);
}
/*
@@ -1152,7 +1310,6 @@ dt_provimpl_t dt_uprobe = {
.load_prog = &dt_bpf_prog_load,
.trampoline = &trampoline,
.attach = &attach,
- .probe_info = &probe_info,
.detach = &detach,
.probe_destroy = &probe_destroy_underlying,
.add_probe = &add_probe_uprobe,
@@ -1178,6 +1335,7 @@ dt_provimpl_t dt_usdt = {
.populate = &populate_usdt,
.provide_probe = &provide_usdt_probe,
.enable = &enable_usdt,
+ .probe_info = &probe_info,
.probe_destroy = &probe_destroy,
.discover = &discover,
.add_probe = &add_probe_usdt,
diff --git a/test/triggers/usdt-tst-argmap-prov.d b/test/triggers/usdt-tst-argmap-prov.d
index 28134baa6fa3..d8c3e88c4616 100644
--- a/test/triggers/usdt-tst-argmap-prov.d
+++ b/test/triggers/usdt-tst-argmap-prov.d
@@ -1,10 +1,13 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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 test_prov {
probe place(int i, int j) : (int j, int i, int i, int j);
+ probe place2(int i, char *j) : (char *j, int i, int i, char *j);
+ probe place3(int i, char *j) : (char *j);
+ probe place4(int i, char *j) : ();
};
diff --git a/test/triggers/usdt-tst-argmap.c b/test/triggers/usdt-tst-argmap.c
index 89a0a53fc1d5..9244092514ff 100644
--- a/test/triggers/usdt-tst-argmap.c
+++ b/test/triggers/usdt-tst-argmap.c
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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.
*/
@@ -12,6 +12,9 @@ main(int argc, char **argv)
{
for (;;) {
DTRACE_PROBE2(test_prov, place, 10, 4);
+ DTRACE_PROBE(test_prov, place2, 255, "foo");
+ DTRACE_PROBE(test_prov, place3, 126, "bar");
+ DTRACE_PROBE(test_prov, place4, 204, "baz");
}
return 0;
diff --git a/test/unittest/dtrace-util/tst.ListProbesArgsUSDT.r b/test/unittest/dtrace-util/tst.ListProbesArgsUSDT.r
new file mode 100644
index 000000000000..d2e280e5f21c
--- /dev/null
+++ b/test/unittest/dtrace-util/tst.ListProbesArgsUSDT.r
@@ -0,0 +1,130 @@
+ ID PROVIDER MODULE FUNCTION NAME
+ XX test_provXXXX test main go_vanishing
+
+ Probe Description Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Types
+ None
+
+ XX test_provXXXX test main go_halved
+
+ Probe Description Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Types
+ args[0]: char *
+
+ XX test_provXXXX test main go_doubled
+
+ Probe Description Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Types
+ args[0]: char *
+ args[1]: int
+ args[2]: int
+ args[3]: char *
+
+ XX test_provXXXX test main go
+
+ Probe Description Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Types
+ args[0]: char *
+ args[1]: int
+
+ ID PROVIDER MODULE FUNCTION NAME
+ XX test_provXXXX test main go_vanishing
+
+ Probe Description Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Types
+ None
+
+ XX test_provXXXX test main go_halved
+
+ Probe Description Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Types
+ args[0]: char *
+
+ XX test_provXXXX test main go_doubled
+
+ Probe Description Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Types
+ args[0]: char *
+ args[1]: int
+ args[2]: int
+ args[3]: char *
+
+ XX test_provXXXX test main go
+
+ Probe Description Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Attributes
+ Identifier Names: Private
+ Data Semantics: Private
+ Dependency Class: Unknown
+
+ Argument Types
+ args[0]: char *
+ args[1]: int
+
diff --git a/test/unittest/dtrace-util/tst.ListProbesArgsUSDT.r.p b/test/unittest/dtrace-util/tst.ListProbesArgsUSDT.r.p
new file mode 100755
index 000000000000..c575983adf65
--- /dev/null
+++ b/test/unittest/dtrace-util/tst.ListProbesArgsUSDT.r.p
@@ -0,0 +1,2 @@
+#!/bin/sed -rf
+s,test_prov[0-9]*,test_provXXXX,g; s,^ *[0-9]+, XX,g;
diff --git a/test/unittest/dtrace-util/tst.ListProbesArgsUSDT.sh b/test/unittest/dtrace-util/tst.ListProbesArgsUSDT.sh
new file mode 100755
index 000000000000..b0a2345a6681
--- /dev/null
+++ b/test/unittest/dtrace-util/tst.ListProbesArgsUSDT.sh
@@ -0,0 +1,89 @@
+#!/bin/bash
+#
+# Oracle Linux DTrace.
+# Copyright (c) 2013, 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.
+
+##
+#
+# ASSERTION:
+# Testing -lvn option with USDT probes with a valid probe name.
+#
+# SECTION: dtrace Utility/-ln Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+CC=/usr/bin/gcc
+CFLAGS=
+
+DIRNAME="$tmpdir/list-probes-args-usdt.$$.$RANDOM"
+mkdir -p $DIRNAME
+cd $DIRNAME
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go(int a, char *b) : (char *b, int a);
+ probe go_doubled(int a, char *b) : (char *b, int a, int a, char *b);
+ probe go_halved(int a, char *b) : (char *b);
+ probe go_vanishing(int a, char *b) : ();
+};
+EOF
+
+$dtrace -h -s prov.d
+if [ $? -ne 0 ]; then
+ echo "failed to generate header file" >& 2
+ exit 1
+fi
+
+cat > test.c <<EOF
+#include <sys/types.h>
+#include "prov.h"
+
+int
+main(int argc, char **argv)
+{
+ TEST_PROV_GO(666, "foo");
+ TEST_PROV_GO_DOUBLED(666, "foo");
+ TEST_PROV_GO_HALVED(666, "foo");
+ TEST_PROV_GO_VANISHING(666, "foo");
+ sleep(10);
+}
+EOF
+
+${CC} ${CFLAGS} -c test.c
+if [ $? -ne 0 ]; then
+ echo "failed to compile test.c" >& 2
+ exit 1
+fi
+$dtrace -G -s prov.d test.o
+if [ $? -ne 0 ]; then
+ echo "failed to create DOF" >& 2
+ exit 1
+fi
+${CC} ${CFLAGS} -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ echo "failed to link final executable" >& 2
+ exit 1
+fi
+
+script()
+{
+ $dtrace -c ./test -lvn 'test_prov$target:::go*'
+ ./test &
+ PID=$!
+ disown %+
+ $dtrace -p $PID -lvn 'test_prov$target:::go*'
+ kill -9 $PID
+}
+
+script
+status=$?
+
+exit $status
diff --git a/test/unittest/usdt/err.argmap-null.d b/test/unittest/usdt/err.argmap-null.d
new file mode 100644
index 000000000000..ba765bea7a04
--- /dev/null
+++ b/test/unittest/usdt/err.argmap-null.d
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/* @@trigger: usdt-tst-argmap */
+/* @@trigger-timing: before */
+/* @@runtest-opts: $_pid */
+
+/*
+ * ASSERTION: Verify that a probe left with no args at all due to mapping
+ * has no args.
+ */
+
+BEGIN
+{
+ /* Timeout after 5 seconds */
+ timeout = timestamp + 5000000000;
+}
+
+test_prov$1:::place4
+/args[0] != 204 || args[0] == 204/
+{
+ printf("this should never happen");
+ exit(1);
+}
+
+test_prov$1:::place4
+{
+ printf("nor should this");
+ exit(1);
+}
+
+profile:::tick-1
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
diff --git a/test/unittest/usdt/err.argmap-null.r b/test/unittest/usdt/err.argmap-null.r
new file mode 100644
index 000000000000..215475e39b48
--- /dev/null
+++ b/test/unittest/usdt/err.argmap-null.r
@@ -0,0 +1,2 @@
+-- @@stderr --
+dtrace: failed to compile script test/unittest/usdt/err.argmap-null.d: line 24: index 0 is out of range for test_provXXXX:::place4 args[ ]
diff --git a/test/unittest/usdt/err.argmap-null.r.p b/test/unittest/usdt/err.argmap-null.r.p
new file mode 100755
index 000000000000..c575983adf65
--- /dev/null
+++ b/test/unittest/usdt/err.argmap-null.r.p
@@ -0,0 +1,2 @@
+#!/bin/sed -rf
+s,test_prov[0-9]*,test_provXXXX,g; s,^ *[0-9]+, XX,g;
diff --git a/test/unittest/usdt/tst.argmap-null.d b/test/unittest/usdt/tst.argmap-null.d
new file mode 100644
index 000000000000..dacf4c4f569a
--- /dev/null
+++ b/test/unittest/usdt/tst.argmap-null.d
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/* @@trigger: usdt-tst-argmap */
+/* @@trigger-timing: before */
+/* @@runtest-opts: $_pid */
+
+/*
+ * ASSERTION: Verify that you can map to no args at all.
+ */
+
+BEGIN
+{
+ /* Timeout after 5 seconds */
+ timeout = timestamp + 5000000000;
+}
+
+test_prov$1:::place4
+{
+ exit(0);
+}
+
+profile:::tick-1
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
diff --git a/test/unittest/usdt/tst.argmap-typed-partial.d b/test/unittest/usdt/tst.argmap-typed-partial.d
new file mode 100644
index 000000000000..8c4d7273c0ab
--- /dev/null
+++ b/test/unittest/usdt/tst.argmap-typed-partial.d
@@ -0,0 +1,49 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2007, 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.
+ */
+
+/* @@trigger: usdt-tst-argmap */
+/* @@trigger-timing: before */
+/* @@runtest-opts: $_pid */
+
+/*
+ * ASSERTION: Verify that args[N] variables are properly typed when mapped,
+ * even if some args are unused.
+ */
+
+BEGIN
+{
+ /* Timeout after 5 seconds */
+ timeout = timestamp + 5000000000;
+}
+
+test_prov$1:::place3
+/stringof(args[0]) != "bar"/
+{
+ printf("arg is %s; should be \"bar\"",
+ stringof(args[0]));
+ exit(1);
+}
+
+test_prov$1:::place3
+/stringof(copyinstr(arg0)) != "bar"/
+{
+ printf("arg is %s; should be \"bar\"",
+ stringof(copyinstr(arg0)));
+ exit(1);
+}
+
+test_prov$1:::place3
+{
+ exit(0);
+}
+
+profile:::tick-1
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
diff --git a/test/unittest/usdt/tst.argmap-typed.d b/test/unittest/usdt/tst.argmap-typed.d
new file mode 100644
index 000000000000..1243e059b8ae
--- /dev/null
+++ b/test/unittest/usdt/tst.argmap-typed.d
@@ -0,0 +1,48 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2007, 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.
+ */
+
+/* @@trigger: usdt-tst-argmap */
+/* @@trigger-timing: before */
+/* @@runtest-opts: $_pid */
+
+/*
+ * ASSERTION: Verify that args[N] variables are properly typed when mapped.
+ */
+
+BEGIN
+{
+ /* Timeout after 5 seconds */
+ timeout = timestamp + 5000000000;
+}
+
+test_prov$1:::place2
+/stringof(args[0]) != "foo" || args[1] != 255 || args[2] != 255 || stringof(args[3]) != "foo"/
+{
+ printf("args are %s, %d, %d, %s; should be \"foo\", 255, 255, \"foo\"",
+ stringof(args[0]), args[1], args[2], stringof(args[3]));
+ exit(1);
+}
+
+test_prov$1:::place2
+/stringof(copyinstr(arg0)) != "foo" || arg1 != 255 || arg2 != 255 || stringof(copyinstr(arg3)) != "foo"/
+{
+ printf("args are %s, %d, %d, %s; should be \"foo\", 255, 255, \"foo\"",
+ stringof(copyinstr(arg0)), arg1, arg2, stringof(copyinstr(arg3)));
+ exit(1);
+}
+
+test_prov$1:::place2
+{
+ exit(0);
+}
+
+profile:::tick-1
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
diff --git a/test/unittest/usdt/tst.argmap.d b/test/unittest/usdt/tst.argmap.d
index 7896dc07e0e2..a7d68da3dfbc 100644
--- a/test/unittest/usdt/tst.argmap.d
+++ b/test/unittest/usdt/tst.argmap.d
@@ -1,17 +1,16 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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.
*/
-/* @@xfail: dtv2 */
/* @@trigger: usdt-tst-argmap */
/* @@trigger-timing: before */
/* @@runtest-opts: $_pid */
/*
- * ASSERTION: Verify that argN and args[N] variables are properly remapped.
+ * ASSERTION: Verify that argN and args[N] variables are properly mapped.
*/
BEGIN
--
2.46.0.278.g36e3a12567
More information about the DTrace-devel
mailing list