[DTrace-devel] [PATCH v2] usdt, stapsdt: fix argument handling for multi-location probes

Kris Van Hees kris.van.hees at oracle.com
Wed Feb 4 13:10:59 UTC 2026


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 at 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



More information about the DTrace-devel mailing list