Re: [PATCH v2] usdt, stapsdt: fix argument handling for multi-location probes
Eugene Loh <[email protected]> Wed, 4 Feb 2026 08:12:26 -0500
| Newsgroups | dev.linux.lists.dtrace |
|---|---|
| Message-ID | <[email protected]> |
Reviewed-by: Eugene Loh <[email protected]> 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 <[email protected]> >>> --- >>> 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