* [PATCH v2] usdt, stapsdt: fix argument handling for multi-location probes
@ 2026-02-04 2:06 Kris Van Hees
2026-02-04 6:25 ` Eugene Loh
0 siblings, 1 reply; 4+ messages in thread
From: Kris Van Hees @ 2026-02-04 2:06 UTC (permalink / raw)
To: dtrace, dtrace-devel
When a USDT probe has multiple call sites in the same function, only one
of the probe programs retrieves the argument values correctly. The
probe argument data is collected for the first underlying probe, and then
skipped for any subsequent underlying probes.
Since it is not guaranteed that the argument description is identical for
all underlying probes (although it is almost always that way), we need to
process the argument description string for each underlying probe.
Orabug: 38922360
Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
---
libdtrace/dt_pid.c | 9 ++-
libdtrace/dt_prov_uprobe.c | 10 +--
test/unittest/usdt/tst.multiloc.r | 4 ++
test/unittest/usdt/tst.multiloc.sh | 69 +++++++++++++++++++
.../usdt/tst.stapsdt-notes-bug38922360.r | 4 ++
.../usdt/tst.stapsdt-notes-bug38922360.sh | 54 +++++++++++++++
6 files changed, 140 insertions(+), 10 deletions(-)
create mode 100644 test/unittest/usdt/tst.multiloc.r
create mode 100755 test/unittest/usdt/tst.multiloc.sh
create mode 100644 test/unittest/usdt/tst.stapsdt-notes-bug38922360.r
create mode 100755 test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh
diff --git a/libdtrace/dt_pid.c b/libdtrace/dt_pid.c
index 6f93123f..a379a0fe 100644
--- a/libdtrace/dt_pid.c
+++ b/libdtrace/dt_pid.c
@@ -1350,9 +1350,16 @@ dt_stapsdt_parse(dtrace_hdl_t *dtp, dt_proc_t *dpr, dtrace_probedesc_t *pdp,
if (strcmp(pdp->prb, "*") != 0 &&
(strlen(pdp->prb) > 0 && strcmp(pdp->prb, prbname) != 0))
continue;
- if (prb + strlen(prb) + 1 < dbuf + doff + nhdr.n_descsz)
+ if (prb + strlen(prb) + 1 < dbuf + doff + nhdr.n_descsz) {
+ char *p;
+
psp.pps_sargv = prb + strlen(prb) + 1;
+ for (p = psp.pps_sargv; (p = strchr(p, '@')) != NULL;
+ p++)
+ psp.pps_nargc++;
+ }
+
psp.pps_type = DTPPT_STAPSDT;
psp.pps_prv = prvname;
psp.pps_mod = mod;
diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
index 6d1c0f65..e575b072 100644
--- a/libdtrace/dt_prov_uprobe.c
+++ b/libdtrace/dt_prov_uprobe.c
@@ -1659,15 +1659,7 @@ static int probe_info_stap(dtrace_hdl_t *dtp, const dt_probe_t *prp,
if (!upp || upp->sargv == NULL)
goto done;
- /* First count the arguments. */
- for (p = upp->sargv; p != NULL; argc++) {
- p = strchr(p, '@');
- if (p++ == NULL)
- break;
- }
-
- /* Record number of arguments, and allocate descriptors. */
- upp->sargc = argc;
+ argc = upp->sargc;
if (argc == 0)
goto done;
diff --git a/test/unittest/usdt/tst.multiloc.r b/test/unittest/usdt/tst.multiloc.r
new file mode 100644
index 00000000..a0bbc7a8
--- /dev/null
+++ b/test/unittest/usdt/tst.multiloc.r
@@ -0,0 +1,4 @@
+main
+test:main:args main
+test:main:args main
+
diff --git a/test/unittest/usdt/tst.multiloc.sh b/test/unittest/usdt/tst.multiloc.sh
new file mode 100755
index 00000000..19d5d6c1
--- /dev/null
+++ b/test/unittest/usdt/tst.multiloc.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+#
+# Oracle Linux DTrace.
+# Copyright (c) 2026, 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 covers USDT probes firing from multiple locations in the same
+# function, verifying that argument data is correct.
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+CFLAGS="-std=gnu89 $test_cppflags"
+LDFLAGS="$test_ldflags"
+
+DIRNAME="$tmpdir/usdt-multiloc.$$.$RANDOM"
+mkdir -p $DIRNAME
+cd $DIRNAME
+
+cat > test.c <<EOF
+#include <sys/sdt.h>
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ printf("%s\n", __func__);
+ DTRACE_PROBE1(test_prov, args, __func__);
+ DTRACE_PROBE1(test_prov, args, __func__);
+}
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe args(char *);
+};
+EOF
+
+${CC} ${CFLAGS} -c test.c
+if [ $? -ne 0 ]; then
+ echo "failed to compile test.c" >& 2
+ exit 1
+fi
+$dtrace $dt_flags -G -s prov.d test.o
+if [ $? -ne 0 ]; then
+ echo "failed to create DOF" >& 2
+ exit 1
+fi
+${CC} ${LDFLAGS} -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ echo "failed to link final executable" >& 2
+ exit 1
+fi
+
+$dtrace $dt_flags -c './test arg1val' -qs /dev/stdin <<EOF
+test_prov\$target:::args
+{
+ printf("%s:%s:%s %s\n", probemod, probefunc, probename,
+ copyinstr(arg0));
+}
+
+EOF
+status=$?
+
+exit $status
diff --git a/test/unittest/usdt/tst.stapsdt-notes-bug38922360.r b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.r
new file mode 100644
index 00000000..a0bbc7a8
--- /dev/null
+++ b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.r
@@ -0,0 +1,4 @@
+main
+test:main:args main
+test:main:args main
+
diff --git a/test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh
new file mode 100755
index 00000000..ea0d6880
--- /dev/null
+++ b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+#
+# Oracle Linux DTrace.
+# Copyright (c) 2026, 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 covers stapsdt probes fired by the STAP_PROBEn macros, verifying
+# that argument data is processed correctly when the same probe is used in
+# multiple locations.
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+CFLAGS="-std=gnu89 -I${PWD}/test/unittest/usdt $test_cppflags"
+LDFLAGS="$test_ldflags"
+
+DIRNAME="$tmpdir/usdt-notes-bug38922360.$$.$RANDOM"
+mkdir -p $DIRNAME
+cd $DIRNAME
+
+cat > test.c <<EOF
+#include <sdt_notes.h>
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ printf("%s\n", __func__);
+ STAP_PROBE1(test_prov, args, __func__);
+ STAP_PROBE1(test_prov, args, __func__);
+}
+EOF
+
+${CC} ${CFLAGS} -o test test.c
+if [ $? -ne 0 ]; then
+ echo "failed to compile test.c" >& 2
+ exit 1
+fi
+
+$dtrace -c './test arg1val' -qs /dev/stdin <<EOF
+test_prov\$target:::args
+{
+ printf("%s:%s:%s %s\n", probemod, probefunc, probename,
+ copyinstr(arg0));
+}
+
+EOF
+status=$?
+
+exit $status
--
2.43.7
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2] usdt, stapsdt: fix argument handling for multi-location probes
2026-02-04 2:06 [PATCH v2] usdt, stapsdt: fix argument handling for multi-location probes Kris Van Hees
@ 2026-02-04 6:25 ` Eugene Loh
2026-02-04 13:10 ` Kris Van Hees
0 siblings, 1 reply; 4+ messages in thread
From: Eugene Loh @ 2026-02-04 6:25 UTC (permalink / raw)
To: Kris Van Hees, dtrace, dtrace-devel
Thanks. The tests pass on all platforms I tried.
I did want to check something. The subject line says both usdt and
stapsdt. The commit message talks of usdt. The bug report indicts both
usdt and stapsdt.
So, there is a problem with stapsdt; the patch fixes and tests that.
That much is great.
However, the new multiloc usdt test seems to pass for me even without
the fix. So was there a usdt problem? Is the multiloc usdt test good
enough to show it?
On 2/3/26 21:06, Kris Van Hees wrote:
> When a USDT probe has multiple call sites in the same function, only one
> of the probe programs retrieves the argument values correctly. The
> probe argument data is collected for the first underlying probe, and then
> skipped for any subsequent underlying probes.
>
> Since it is not guaranteed that the argument description is identical for
> all underlying probes (although it is almost always that way), we need to
> process the argument description string for each underlying probe.
>
> Orabug: 38922360
> Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
> ---
> libdtrace/dt_pid.c | 9 ++-
> libdtrace/dt_prov_uprobe.c | 10 +--
> test/unittest/usdt/tst.multiloc.r | 4 ++
> test/unittest/usdt/tst.multiloc.sh | 69 +++++++++++++++++++
> .../usdt/tst.stapsdt-notes-bug38922360.r | 4 ++
> .../usdt/tst.stapsdt-notes-bug38922360.sh | 54 +++++++++++++++
> 6 files changed, 140 insertions(+), 10 deletions(-)
> create mode 100644 test/unittest/usdt/tst.multiloc.r
> create mode 100755 test/unittest/usdt/tst.multiloc.sh
> create mode 100644 test/unittest/usdt/tst.stapsdt-notes-bug38922360.r
> create mode 100755 test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh
>
> diff --git a/libdtrace/dt_pid.c b/libdtrace/dt_pid.c
> index 6f93123f..a379a0fe 100644
> --- a/libdtrace/dt_pid.c
> +++ b/libdtrace/dt_pid.c
> @@ -1350,9 +1350,16 @@ dt_stapsdt_parse(dtrace_hdl_t *dtp, dt_proc_t *dpr, dtrace_probedesc_t *pdp,
> if (strcmp(pdp->prb, "*") != 0 &&
> (strlen(pdp->prb) > 0 && strcmp(pdp->prb, prbname) != 0))
> continue;
> - if (prb + strlen(prb) + 1 < dbuf + doff + nhdr.n_descsz)
> + if (prb + strlen(prb) + 1 < dbuf + doff + nhdr.n_descsz) {
> + char *p;
> +
> psp.pps_sargv = prb + strlen(prb) + 1;
>
> + for (p = psp.pps_sargv; (p = strchr(p, '@')) != NULL;
> + p++)
> + psp.pps_nargc++;
> + }
> +
> psp.pps_type = DTPPT_STAPSDT;
> psp.pps_prv = prvname;
> psp.pps_mod = mod;
> diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
> index 6d1c0f65..e575b072 100644
> --- a/libdtrace/dt_prov_uprobe.c
> +++ b/libdtrace/dt_prov_uprobe.c
> @@ -1659,15 +1659,7 @@ static int probe_info_stap(dtrace_hdl_t *dtp, const dt_probe_t *prp,
> if (!upp || upp->sargv == NULL)
> goto done;
>
> - /* First count the arguments. */
> - for (p = upp->sargv; p != NULL; argc++) {
> - p = strchr(p, '@');
> - if (p++ == NULL)
> - break;
> - }
> -
> - /* Record number of arguments, and allocate descriptors. */
> - upp->sargc = argc;
> + argc = upp->sargc;
> if (argc == 0)
> goto done;
>
> diff --git a/test/unittest/usdt/tst.multiloc.r b/test/unittest/usdt/tst.multiloc.r
> new file mode 100644
> index 00000000..a0bbc7a8
> --- /dev/null
> +++ b/test/unittest/usdt/tst.multiloc.r
> @@ -0,0 +1,4 @@
> +main
> +test:main:args main
> +test:main:args main
> +
> diff --git a/test/unittest/usdt/tst.multiloc.sh b/test/unittest/usdt/tst.multiloc.sh
> new file mode 100755
> index 00000000..19d5d6c1
> --- /dev/null
> +++ b/test/unittest/usdt/tst.multiloc.sh
> @@ -0,0 +1,69 @@
> +#!/bin/bash
> +#
> +# Oracle Linux DTrace.
> +# Copyright (c) 2026, 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 covers USDT probes firing from multiple locations in the same
> +# function, verifying that argument data is correct.
> +
> +if [ $# != 1 ]; then
> + echo expected one argument: '<'dtrace-path'>'
> + exit 2
> +fi
> +
> +dtrace=$1
> +CFLAGS="-std=gnu89 $test_cppflags"
> +LDFLAGS="$test_ldflags"
> +
> +DIRNAME="$tmpdir/usdt-multiloc.$$.$RANDOM"
> +mkdir -p $DIRNAME
> +cd $DIRNAME
> +
> +cat > test.c <<EOF
> +#include <sys/sdt.h>
> +#include <stdio.h>
> +
> +int
> +main(int argc, char **argv)
> +{
> + printf("%s\n", __func__);
> + DTRACE_PROBE1(test_prov, args, __func__);
> + DTRACE_PROBE1(test_prov, args, __func__);
> +}
> +EOF
> +
> +cat > prov.d <<EOF
> +provider test_prov {
> + probe args(char *);
> +};
> +EOF
> +
> +${CC} ${CFLAGS} -c test.c
> +if [ $? -ne 0 ]; then
> + echo "failed to compile test.c" >& 2
> + exit 1
> +fi
> +$dtrace $dt_flags -G -s prov.d test.o
> +if [ $? -ne 0 ]; then
> + echo "failed to create DOF" >& 2
> + exit 1
> +fi
> +${CC} ${LDFLAGS} -o test test.o prov.o
> +if [ $? -ne 0 ]; then
> + echo "failed to link final executable" >& 2
> + exit 1
> +fi
> +
> +$dtrace $dt_flags -c './test arg1val' -qs /dev/stdin <<EOF
> +test_prov\$target:::args
> +{
> + printf("%s:%s:%s %s\n", probemod, probefunc, probename,
> + copyinstr(arg0));
> +}
> +
> +EOF
> +status=$?
> +
> +exit $status
> diff --git a/test/unittest/usdt/tst.stapsdt-notes-bug38922360.r b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.r
> new file mode 100644
> index 00000000..a0bbc7a8
> --- /dev/null
> +++ b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.r
> @@ -0,0 +1,4 @@
> +main
> +test:main:args main
> +test:main:args main
> +
> diff --git a/test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh
> new file mode 100755
> index 00000000..ea0d6880
> --- /dev/null
> +++ b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh
> @@ -0,0 +1,54 @@
> +#!/bin/bash
> +#
> +# Oracle Linux DTrace.
> +# Copyright (c) 2026, 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 covers stapsdt probes fired by the STAP_PROBEn macros, verifying
> +# that argument data is processed correctly when the same probe is used in
> +# multiple locations.
> +
> +if [ $# != 1 ]; then
> + echo expected one argument: '<'dtrace-path'>'
> + exit 2
> +fi
> +
> +dtrace=$1
> +CFLAGS="-std=gnu89 -I${PWD}/test/unittest/usdt $test_cppflags"
> +LDFLAGS="$test_ldflags"
> +
> +DIRNAME="$tmpdir/usdt-notes-bug38922360.$$.$RANDOM"
> +mkdir -p $DIRNAME
> +cd $DIRNAME
> +
> +cat > test.c <<EOF
> +#include <sdt_notes.h>
> +#include <stdio.h>
> +
> +int
> +main(int argc, char **argv)
> +{
> + printf("%s\n", __func__);
> + STAP_PROBE1(test_prov, args, __func__);
> + STAP_PROBE1(test_prov, args, __func__);
> +}
> +EOF
> +
> +${CC} ${CFLAGS} -o test test.c
> +if [ $? -ne 0 ]; then
> + echo "failed to compile test.c" >& 2
> + exit 1
> +fi
> +
> +$dtrace -c './test arg1val' -qs /dev/stdin <<EOF
> +test_prov\$target:::args
> +{
> + printf("%s:%s:%s %s\n", probemod, probefunc, probename,
> + copyinstr(arg0));
> +}
> +
> +EOF
> +status=$?
> +
> +exit $status
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2] usdt, stapsdt: fix argument handling for multi-location probes
2026-02-04 6:25 ` Eugene Loh
@ 2026-02-04 13:10 ` Kris Van Hees
2026-02-04 13:12 ` Eugene Loh
0 siblings, 1 reply; 4+ messages in thread
From: Kris Van Hees @ 2026-02-04 13:10 UTC (permalink / raw)
To: Eugene Loh; +Cc: Kris Van Hees, dtrace, dtrace-devel
On Wed, Feb 04, 2026 at 01:25:03AM -0500, Eugene Loh wrote:
> Thanks. The tests pass on all platforms I tried.
>
> I did want to check something. The subject line says both usdt and
> stapsdt. The commit message talks of usdt. The bug report indicts both
> usdt and stapsdt.
>
> So, there is a problem with stapsdt; the patch fixes and tests that. That
> much is great.
>
> However, the new multiloc usdt test seems to pass for me even without the
> fix. So was there a usdt problem? Is the multiloc usdt test good enough to
> show it?
The problem does not occur with regula USDT but there is also nothing that
actually tests for this, so I added it as a precaution for future regression.
> On 2/3/26 21:06, Kris Van Hees wrote:
>
> > When a USDT probe has multiple call sites in the same function, only one
> > of the probe programs retrieves the argument values correctly. The
> > probe argument data is collected for the first underlying probe, and then
> > skipped for any subsequent underlying probes.
> >
> > Since it is not guaranteed that the argument description is identical for
> > all underlying probes (although it is almost always that way), we need to
> > process the argument description string for each underlying probe.
> >
> > Orabug: 38922360
> > Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
> > ---
> > libdtrace/dt_pid.c | 9 ++-
> > libdtrace/dt_prov_uprobe.c | 10 +--
> > test/unittest/usdt/tst.multiloc.r | 4 ++
> > test/unittest/usdt/tst.multiloc.sh | 69 +++++++++++++++++++
> > .../usdt/tst.stapsdt-notes-bug38922360.r | 4 ++
> > .../usdt/tst.stapsdt-notes-bug38922360.sh | 54 +++++++++++++++
> > 6 files changed, 140 insertions(+), 10 deletions(-)
> > create mode 100644 test/unittest/usdt/tst.multiloc.r
> > create mode 100755 test/unittest/usdt/tst.multiloc.sh
> > create mode 100644 test/unittest/usdt/tst.stapsdt-notes-bug38922360.r
> > create mode 100755 test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh
> >
> > diff --git a/libdtrace/dt_pid.c b/libdtrace/dt_pid.c
> > index 6f93123f..a379a0fe 100644
> > --- a/libdtrace/dt_pid.c
> > +++ b/libdtrace/dt_pid.c
> > @@ -1350,9 +1350,16 @@ dt_stapsdt_parse(dtrace_hdl_t *dtp, dt_proc_t *dpr, dtrace_probedesc_t *pdp,
> > if (strcmp(pdp->prb, "*") != 0 &&
> > (strlen(pdp->prb) > 0 && strcmp(pdp->prb, prbname) != 0))
> > continue;
> > - if (prb + strlen(prb) + 1 < dbuf + doff + nhdr.n_descsz)
> > + if (prb + strlen(prb) + 1 < dbuf + doff + nhdr.n_descsz) {
> > + char *p;
> > +
> > psp.pps_sargv = prb + strlen(prb) + 1;
> > + for (p = psp.pps_sargv; (p = strchr(p, '@')) != NULL;
> > + p++)
> > + psp.pps_nargc++;
> > + }
> > +
> > psp.pps_type = DTPPT_STAPSDT;
> > psp.pps_prv = prvname;
> > psp.pps_mod = mod;
> > diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
> > index 6d1c0f65..e575b072 100644
> > --- a/libdtrace/dt_prov_uprobe.c
> > +++ b/libdtrace/dt_prov_uprobe.c
> > @@ -1659,15 +1659,7 @@ static int probe_info_stap(dtrace_hdl_t *dtp, const dt_probe_t *prp,
> > if (!upp || upp->sargv == NULL)
> > goto done;
> > - /* First count the arguments. */
> > - for (p = upp->sargv; p != NULL; argc++) {
> > - p = strchr(p, '@');
> > - if (p++ == NULL)
> > - break;
> > - }
> > -
> > - /* Record number of arguments, and allocate descriptors. */
> > - upp->sargc = argc;
> > + argc = upp->sargc;
> > if (argc == 0)
> > goto done;
> > diff --git a/test/unittest/usdt/tst.multiloc.r b/test/unittest/usdt/tst.multiloc.r
> > new file mode 100644
> > index 00000000..a0bbc7a8
> > --- /dev/null
> > +++ b/test/unittest/usdt/tst.multiloc.r
> > @@ -0,0 +1,4 @@
> > +main
> > +test:main:args main
> > +test:main:args main
> > +
> > diff --git a/test/unittest/usdt/tst.multiloc.sh b/test/unittest/usdt/tst.multiloc.sh
> > new file mode 100755
> > index 00000000..19d5d6c1
> > --- /dev/null
> > +++ b/test/unittest/usdt/tst.multiloc.sh
> > @@ -0,0 +1,69 @@
> > +#!/bin/bash
> > +#
> > +# Oracle Linux DTrace.
> > +# Copyright (c) 2026, 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 covers USDT probes firing from multiple locations in the same
> > +# function, verifying that argument data is correct.
> > +
> > +if [ $# != 1 ]; then
> > + echo expected one argument: '<'dtrace-path'>'
> > + exit 2
> > +fi
> > +
> > +dtrace=$1
> > +CFLAGS="-std=gnu89 $test_cppflags"
> > +LDFLAGS="$test_ldflags"
> > +
> > +DIRNAME="$tmpdir/usdt-multiloc.$$.$RANDOM"
> > +mkdir -p $DIRNAME
> > +cd $DIRNAME
> > +
> > +cat > test.c <<EOF
> > +#include <sys/sdt.h>
> > +#include <stdio.h>
> > +
> > +int
> > +main(int argc, char **argv)
> > +{
> > + printf("%s\n", __func__);
> > + DTRACE_PROBE1(test_prov, args, __func__);
> > + DTRACE_PROBE1(test_prov, args, __func__);
> > +}
> > +EOF
> > +
> > +cat > prov.d <<EOF
> > +provider test_prov {
> > + probe args(char *);
> > +};
> > +EOF
> > +
> > +${CC} ${CFLAGS} -c test.c
> > +if [ $? -ne 0 ]; then
> > + echo "failed to compile test.c" >& 2
> > + exit 1
> > +fi
> > +$dtrace $dt_flags -G -s prov.d test.o
> > +if [ $? -ne 0 ]; then
> > + echo "failed to create DOF" >& 2
> > + exit 1
> > +fi
> > +${CC} ${LDFLAGS} -o test test.o prov.o
> > +if [ $? -ne 0 ]; then
> > + echo "failed to link final executable" >& 2
> > + exit 1
> > +fi
> > +
> > +$dtrace $dt_flags -c './test arg1val' -qs /dev/stdin <<EOF
> > +test_prov\$target:::args
> > +{
> > + printf("%s:%s:%s %s\n", probemod, probefunc, probename,
> > + copyinstr(arg0));
> > +}
> > +
> > +EOF
> > +status=$?
> > +
> > +exit $status
> > diff --git a/test/unittest/usdt/tst.stapsdt-notes-bug38922360.r b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.r
> > new file mode 100644
> > index 00000000..a0bbc7a8
> > --- /dev/null
> > +++ b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.r
> > @@ -0,0 +1,4 @@
> > +main
> > +test:main:args main
> > +test:main:args main
> > +
> > diff --git a/test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh
> > new file mode 100755
> > index 00000000..ea0d6880
> > --- /dev/null
> > +++ b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh
> > @@ -0,0 +1,54 @@
> > +#!/bin/bash
> > +#
> > +# Oracle Linux DTrace.
> > +# Copyright (c) 2026, 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 covers stapsdt probes fired by the STAP_PROBEn macros, verifying
> > +# that argument data is processed correctly when the same probe is used in
> > +# multiple locations.
> > +
> > +if [ $# != 1 ]; then
> > + echo expected one argument: '<'dtrace-path'>'
> > + exit 2
> > +fi
> > +
> > +dtrace=$1
> > +CFLAGS="-std=gnu89 -I${PWD}/test/unittest/usdt $test_cppflags"
> > +LDFLAGS="$test_ldflags"
> > +
> > +DIRNAME="$tmpdir/usdt-notes-bug38922360.$$.$RANDOM"
> > +mkdir -p $DIRNAME
> > +cd $DIRNAME
> > +
> > +cat > test.c <<EOF
> > +#include <sdt_notes.h>
> > +#include <stdio.h>
> > +
> > +int
> > +main(int argc, char **argv)
> > +{
> > + printf("%s\n", __func__);
> > + STAP_PROBE1(test_prov, args, __func__);
> > + STAP_PROBE1(test_prov, args, __func__);
> > +}
> > +EOF
> > +
> > +${CC} ${CFLAGS} -o test test.c
> > +if [ $? -ne 0 ]; then
> > + echo "failed to compile test.c" >& 2
> > + exit 1
> > +fi
> > +
> > +$dtrace -c './test arg1val' -qs /dev/stdin <<EOF
> > +test_prov\$target:::args
> > +{
> > + printf("%s:%s:%s %s\n", probemod, probefunc, probename,
> > + copyinstr(arg0));
> > +}
> > +
> > +EOF
> > +status=$?
> > +
> > +exit $status
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2] usdt, stapsdt: fix argument handling for multi-location probes
2026-02-04 13:10 ` Kris Van Hees
@ 2026-02-04 13:12 ` Eugene Loh
0 siblings, 0 replies; 4+ messages in thread
From: Eugene Loh @ 2026-02-04 13:12 UTC (permalink / raw)
To: Kris Van Hees; +Cc: dtrace, dtrace-devel
Reviewed-by: Eugene Loh <eugene.loh@oracle.com>
On 2/4/26 08:10, Kris Van Hees wrote:
> On Wed, Feb 04, 2026 at 01:25:03AM -0500, Eugene Loh wrote:
>> Thanks. The tests pass on all platforms I tried.
>>
>> I did want to check something. The subject line says both usdt and
>> stapsdt. The commit message talks of usdt. The bug report indicts both
>> usdt and stapsdt.
>>
>> So, there is a problem with stapsdt; the patch fixes and tests that. That
>> much is great.
>>
>> However, the new multiloc usdt test seems to pass for me even without the
>> fix. So was there a usdt problem? Is the multiloc usdt test good enough to
>> show it?
> The problem does not occur with regula USDT but there is also nothing that
> actually tests for this, so I added it as a precaution for future regression.
>
>> On 2/3/26 21:06, Kris Van Hees wrote:
>>
>>> When a USDT probe has multiple call sites in the same function, only one
>>> of the probe programs retrieves the argument values correctly. The
>>> probe argument data is collected for the first underlying probe, and then
>>> skipped for any subsequent underlying probes.
>>>
>>> Since it is not guaranteed that the argument description is identical for
>>> all underlying probes (although it is almost always that way), we need to
>>> process the argument description string for each underlying probe.
>>>
>>> Orabug: 38922360
>>> Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
>>> ---
>>> libdtrace/dt_pid.c | 9 ++-
>>> libdtrace/dt_prov_uprobe.c | 10 +--
>>> test/unittest/usdt/tst.multiloc.r | 4 ++
>>> test/unittest/usdt/tst.multiloc.sh | 69 +++++++++++++++++++
>>> .../usdt/tst.stapsdt-notes-bug38922360.r | 4 ++
>>> .../usdt/tst.stapsdt-notes-bug38922360.sh | 54 +++++++++++++++
>>> 6 files changed, 140 insertions(+), 10 deletions(-)
>>> create mode 100644 test/unittest/usdt/tst.multiloc.r
>>> create mode 100755 test/unittest/usdt/tst.multiloc.sh
>>> create mode 100644 test/unittest/usdt/tst.stapsdt-notes-bug38922360.r
>>> create mode 100755 test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh
>>>
>>> diff --git a/libdtrace/dt_pid.c b/libdtrace/dt_pid.c
>>> index 6f93123f..a379a0fe 100644
>>> --- a/libdtrace/dt_pid.c
>>> +++ b/libdtrace/dt_pid.c
>>> @@ -1350,9 +1350,16 @@ dt_stapsdt_parse(dtrace_hdl_t *dtp, dt_proc_t *dpr, dtrace_probedesc_t *pdp,
>>> if (strcmp(pdp->prb, "*") != 0 &&
>>> (strlen(pdp->prb) > 0 && strcmp(pdp->prb, prbname) != 0))
>>> continue;
>>> - if (prb + strlen(prb) + 1 < dbuf + doff + nhdr.n_descsz)
>>> + if (prb + strlen(prb) + 1 < dbuf + doff + nhdr.n_descsz) {
>>> + char *p;
>>> +
>>> psp.pps_sargv = prb + strlen(prb) + 1;
>>> + for (p = psp.pps_sargv; (p = strchr(p, '@')) != NULL;
>>> + p++)
>>> + psp.pps_nargc++;
>>> + }
>>> +
>>> psp.pps_type = DTPPT_STAPSDT;
>>> psp.pps_prv = prvname;
>>> psp.pps_mod = mod;
>>> diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
>>> index 6d1c0f65..e575b072 100644
>>> --- a/libdtrace/dt_prov_uprobe.c
>>> +++ b/libdtrace/dt_prov_uprobe.c
>>> @@ -1659,15 +1659,7 @@ static int probe_info_stap(dtrace_hdl_t *dtp, const dt_probe_t *prp,
>>> if (!upp || upp->sargv == NULL)
>>> goto done;
>>> - /* First count the arguments. */
>>> - for (p = upp->sargv; p != NULL; argc++) {
>>> - p = strchr(p, '@');
>>> - if (p++ == NULL)
>>> - break;
>>> - }
>>> -
>>> - /* Record number of arguments, and allocate descriptors. */
>>> - upp->sargc = argc;
>>> + argc = upp->sargc;
>>> if (argc == 0)
>>> goto done;
>>> diff --git a/test/unittest/usdt/tst.multiloc.r b/test/unittest/usdt/tst.multiloc.r
>>> new file mode 100644
>>> index 00000000..a0bbc7a8
>>> --- /dev/null
>>> +++ b/test/unittest/usdt/tst.multiloc.r
>>> @@ -0,0 +1,4 @@
>>> +main
>>> +test:main:args main
>>> +test:main:args main
>>> +
>>> diff --git a/test/unittest/usdt/tst.multiloc.sh b/test/unittest/usdt/tst.multiloc.sh
>>> new file mode 100755
>>> index 00000000..19d5d6c1
>>> --- /dev/null
>>> +++ b/test/unittest/usdt/tst.multiloc.sh
>>> @@ -0,0 +1,69 @@
>>> +#!/bin/bash
>>> +#
>>> +# Oracle Linux DTrace.
>>> +# Copyright (c) 2026, 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 covers USDT probes firing from multiple locations in the same
>>> +# function, verifying that argument data is correct.
>>> +
>>> +if [ $# != 1 ]; then
>>> + echo expected one argument: '<'dtrace-path'>'
>>> + exit 2
>>> +fi
>>> +
>>> +dtrace=$1
>>> +CFLAGS="-std=gnu89 $test_cppflags"
>>> +LDFLAGS="$test_ldflags"
>>> +
>>> +DIRNAME="$tmpdir/usdt-multiloc.$$.$RANDOM"
>>> +mkdir -p $DIRNAME
>>> +cd $DIRNAME
>>> +
>>> +cat > test.c <<EOF
>>> +#include <sys/sdt.h>
>>> +#include <stdio.h>
>>> +
>>> +int
>>> +main(int argc, char **argv)
>>> +{
>>> + printf("%s\n", __func__);
>>> + DTRACE_PROBE1(test_prov, args, __func__);
>>> + DTRACE_PROBE1(test_prov, args, __func__);
>>> +}
>>> +EOF
>>> +
>>> +cat > prov.d <<EOF
>>> +provider test_prov {
>>> + probe args(char *);
>>> +};
>>> +EOF
>>> +
>>> +${CC} ${CFLAGS} -c test.c
>>> +if [ $? -ne 0 ]; then
>>> + echo "failed to compile test.c" >& 2
>>> + exit 1
>>> +fi
>>> +$dtrace $dt_flags -G -s prov.d test.o
>>> +if [ $? -ne 0 ]; then
>>> + echo "failed to create DOF" >& 2
>>> + exit 1
>>> +fi
>>> +${CC} ${LDFLAGS} -o test test.o prov.o
>>> +if [ $? -ne 0 ]; then
>>> + echo "failed to link final executable" >& 2
>>> + exit 1
>>> +fi
>>> +
>>> +$dtrace $dt_flags -c './test arg1val' -qs /dev/stdin <<EOF
>>> +test_prov\$target:::args
>>> +{
>>> + printf("%s:%s:%s %s\n", probemod, probefunc, probename,
>>> + copyinstr(arg0));
>>> +}
>>> +
>>> +EOF
>>> +status=$?
>>> +
>>> +exit $status
>>> diff --git a/test/unittest/usdt/tst.stapsdt-notes-bug38922360.r b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.r
>>> new file mode 100644
>>> index 00000000..a0bbc7a8
>>> --- /dev/null
>>> +++ b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.r
>>> @@ -0,0 +1,4 @@
>>> +main
>>> +test:main:args main
>>> +test:main:args main
>>> +
>>> diff --git a/test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh
>>> new file mode 100755
>>> index 00000000..ea0d6880
>>> --- /dev/null
>>> +++ b/test/unittest/usdt/tst.stapsdt-notes-bug38922360.sh
>>> @@ -0,0 +1,54 @@
>>> +#!/bin/bash
>>> +#
>>> +# Oracle Linux DTrace.
>>> +# Copyright (c) 2026, 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 covers stapsdt probes fired by the STAP_PROBEn macros, verifying
>>> +# that argument data is processed correctly when the same probe is used in
>>> +# multiple locations.
>>> +
>>> +if [ $# != 1 ]; then
>>> + echo expected one argument: '<'dtrace-path'>'
>>> + exit 2
>>> +fi
>>> +
>>> +dtrace=$1
>>> +CFLAGS="-std=gnu89 -I${PWD}/test/unittest/usdt $test_cppflags"
>>> +LDFLAGS="$test_ldflags"
>>> +
>>> +DIRNAME="$tmpdir/usdt-notes-bug38922360.$$.$RANDOM"
>>> +mkdir -p $DIRNAME
>>> +cd $DIRNAME
>>> +
>>> +cat > test.c <<EOF
>>> +#include <sdt_notes.h>
>>> +#include <stdio.h>
>>> +
>>> +int
>>> +main(int argc, char **argv)
>>> +{
>>> + printf("%s\n", __func__);
>>> + STAP_PROBE1(test_prov, args, __func__);
>>> + STAP_PROBE1(test_prov, args, __func__);
>>> +}
>>> +EOF
>>> +
>>> +${CC} ${CFLAGS} -o test test.c
>>> +if [ $? -ne 0 ]; then
>>> + echo "failed to compile test.c" >& 2
>>> + exit 1
>>> +fi
>>> +
>>> +$dtrace -c './test arg1val' -qs /dev/stdin <<EOF
>>> +test_prov\$target:::args
>>> +{
>>> + printf("%s:%s:%s %s\n", probemod, probefunc, probename,
>>> + copyinstr(arg0));
>>> +}
>>> +
>>> +EOF
>>> +status=$?
>>> +
>>> +exit $status
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-02-04 13:12 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-04 2:06 [PATCH v2] usdt, stapsdt: fix argument handling for multi-location probes Kris Van Hees
2026-02-04 6:25 ` Eugene Loh
2026-02-04 13:10 ` Kris Van Hees
2026-02-04 13:12 ` Eugene Loh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox