[DTrace-devel] [PATCH v6 7/7] selftests/usdt: add is-enabled stapsdt tests using semaphores
Alan Maguire
alan.maguire at oracle.com
Tue Jul 29 07:37:16 UTC 2025
On 29/07/2025 03:07, Kris Van Hees wrote:
> This test is flawed because you never initialize the semaphores. If you change
> the code to assign 0 to then, then the test fails because the probes never
> fire. That makes sense because your implementation does not actually do
Hmm, I don't see this behaviour. If I change the semaphores to be set to
0, i.e.
-unsigned short test_prov_zero_semaphore SEC(".probes");
-unsigned short test_prov_one_semaphore SEC(".probes");
-unsigned short test_prov_two_semaphore SEC(".probes");
-unsigned short test_prov_three_semaphore SEC(".probes");
-unsigned short test_prov_four_semaphore SEC(".probes");
-unsigned short test_prov_five_semaphore SEC(".probes");
-unsigned short test_prov_six_semaphore SEC(".probes");
-unsigned short test_prov_seven_semaphore SEC(".probes");
-unsigned short test_prov_eight_semaphore SEC(".probes");
-unsigned short test_prov_nine_semaphore SEC(".probes");
-unsigned short test_prov_ten_semaphore SEC(".probes");
-unsigned short test_prov_eleven_semaphore SEC(".probes");
-unsigned short test_prov_twelve_semaphore SEC(".probes");
+unsigned short test_prov_zero_semaphore SEC(".probes") = 0;
+unsigned short test_prov_one_semaphore SEC(".probes") = 0;
+unsigned short test_prov_two_semaphore SEC(".probes") = 0;
+unsigned short test_prov_three_semaphore SEC(".probes") = 0;
+unsigned short test_prov_four_semaphore SEC(".probes") = 0;
+unsigned short test_prov_five_semaphore SEC(".probes") = 0;
+unsigned short test_prov_six_semaphore SEC(".probes") = 0;
+unsigned short test_prov_seven_semaphore SEC(".probes") = 0;
+unsigned short test_prov_eight_semaphore SEC(".probes") = 0;
+unsigned short test_prov_nine_semaphore SEC(".probes") = 0;
+unsigned short test_prov_ten_semaphore SEC(".probes") = 0;
+unsigned short test_prov_eleven_semaphore SEC(".probes") = 0;
+unsigned short test_prov_twelve_semaphore SEC(".probes") = 0;
...the test still passes. Are you perhaps initializing the semaphores in
main()? This has the potential to overwrite the kernel-updated values
which are incremented when the probes are enabled.
> anything with the semaphore, i.e. if the probe it relatees to is enabled,
> nothing happens to the semaphore, so while you do store the address of the
> semaphore in patch 2, it is never used for anything, so this test passing is
The refcntr address is set in parentheses where the probe is set up -
see uprobe_create():
if (refcntr_off) {
if (asprintf(&spec, "%s:0x%lx(0x%lx)", mapping_fn, addr,
refcntr_off) < 0)
return NULL;
} else {
if (asprintf(&spec, "%s:0x%lx", mapping_fn, addr) < 0)
return NULL;
}
The parenthesized value is then handed off to the kernel to
reference-count probe enablings.
> actually accidental because the semaphore initial value is (apparently) most
> commonly *not* 0.
>
> On Mon, Jul 28, 2025 at 05:36:11PM +0100, Alan Maguire wrote:
>> Is-eanbled probes are implemented using semaphores where the
>> semaphore address is specified in the ELF notes and passed
>> in at probe creation time to have the kernel reference-count
>> probes; this allows us to have argument assembly code that
>> only gets executed when the stapsdt probe is in use.
>>
>> Signed-off-by: Alan Maguire <alan.maguire at oracle.com>
>> ---
>> .../usdt/tst.stapsdt-notes-isenabled.r | 14 ++
>> .../usdt/tst.stapsdt-notes-isenabled.sh | 151 ++++++++++++++++++
>> 2 files changed, 165 insertions(+)
>> create mode 100644 test/unittest/usdt/tst.stapsdt-notes-isenabled.r
>> create mode 100755 test/unittest/usdt/tst.stapsdt-notes-isenabled.sh
>>
>> diff --git a/test/unittest/usdt/tst.stapsdt-notes-isenabled.r b/test/unittest/usdt/tst.stapsdt-notes-isenabled.r
>> new file mode 100644
>> index 00000000..db6d18cb
>> --- /dev/null
>> +++ b/test/unittest/usdt/tst.stapsdt-notes-isenabled.r
>> @@ -0,0 +1,14 @@
>> +test:main:zero
>> +test:main:one:1
>> +test:main:two:2:3
>> +test:main:three:4:5:7
>> +test:main:four:7:8:9:10
>> +test:main:five:11:12:13:14:15
>> +test:main:six:16:17:18:19:20:21
>> +test:main:seven:22:23:24:25:26:27:28
>> +test:main:eight:29:30:31:32:33:34:35:36
>> +test:main:nine:37:38:39:40:41:42:43:44:45
>> +test:main:ten:46:47:48:49:50:51:52:53:54:55
>> +test:main:eleven:56:57:58:59:60:61:62:63:64:65
>> +test:main:twelve:67:68:69:70:71:72:73:74:75:76
>> +
>> diff --git a/test/unittest/usdt/tst.stapsdt-notes-isenabled.sh b/test/unittest/usdt/tst.stapsdt-notes-isenabled.sh
>> new file mode 100755
>> index 00000000..99fcc844
>> --- /dev/null
>> +++ b/test/unittest/usdt/tst.stapsdt-notes-isenabled.sh
>> @@ -0,0 +1,151 @@
>> +#!/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 covers all stapsdt probes fired by the STAP_PROBEn macros.
>> +# Arguments values are checked only for first 10 arguments because
>> +# there is support for arg0 ... arg9 only at this moment.
>> +
>> +if [ $# != 1 ]; then
>> + echo expected one argument: '<'dtrace-path'>'
>> + exit 2
>> +fi
>> +
>> +dtrace=$1
>> +CC=/usr/bin/gcc
>> +CFLAGS="-I${PWD}/test/unittest/usdt"
>> +
>> +DIRNAME="$tmpdir/usdt-notes.$$.$RANDOM"
>> +mkdir -p $DIRNAME
>> +cd $DIRNAME
>> +
>> +cat > test.c <<EOF
>> +#define _SDT_HAS_SEMAPHORES 1
>> +#include <sdt_notes.h>
>> +
>> +#define SEC(name) __attribute__((section(name), used))
>> +
>> +unsigned short test_prov_zero_semaphore SEC(".probes");
>> +unsigned short test_prov_one_semaphore SEC(".probes");
>> +unsigned short test_prov_two_semaphore SEC(".probes");
>> +unsigned short test_prov_three_semaphore SEC(".probes");
>> +unsigned short test_prov_four_semaphore SEC(".probes");
>> +unsigned short test_prov_five_semaphore SEC(".probes");
>> +unsigned short test_prov_six_semaphore SEC(".probes");
>> +unsigned short test_prov_seven_semaphore SEC(".probes");
>> +unsigned short test_prov_eight_semaphore SEC(".probes");
>> +unsigned short test_prov_nine_semaphore SEC(".probes");
>> +unsigned short test_prov_ten_semaphore SEC(".probes");
>> +unsigned short test_prov_eleven_semaphore SEC(".probes");
>> +unsigned short test_prov_twelve_semaphore SEC(".probes");
>> +
>> +int
>> +main(int argc, char **argv)
>> +{
>> + if (test_prov_zero_semaphore)
>> + STAP_PROBE(test_prov, zero);
>> + if (test_prov_one_semaphore)
>> + STAP_PROBE1(test_prov, one, argc);
>> + if (test_prov_two_semaphore)
>> + STAP_PROBE2(test_prov, two, 2, 3);
>> + if (test_prov_three_semaphore)
>> + STAP_PROBE3(test_prov, three, 4, 5, 7);
>> + if (test_prov_four_semaphore)
>> + STAP_PROBE4(test_prov, four, 7, 8, 9, 10);
>> + if (test_prov_five_semaphore)
>> + STAP_PROBE5(test_prov, five, 11, 12, 13, 14, 15);
>> + if (test_prov_six_semaphore)
>> + STAP_PROBE6(test_prov, six, 16, 17, 18, 19, 20, 21);
>> + if (test_prov_seven_semaphore)
>> + STAP_PROBE7(test_prov, seven, 22, 23, 24, 25, 26, 27, 28);
>> + if (test_prov_eight_semaphore)
>> + STAP_PROBE8(test_prov, eight, 29, 30, 31, 32, 33, 34, 35, 36);
>> + if (test_prov_nine_semaphore)
>> + STAP_PROBE9(test_prov, nine, 37, 38, 39, 40, 41, 42, 43, 44, 45);
>> + if (test_prov_ten_semaphore)
>> + STAP_PROBE10(test_prov, ten, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55);
>> + if (test_prov_eleven_semaphore)
>> + STAP_PROBE11(test_prov, eleven, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66);
>> + if (test_prov_twelve_semaphore)
>> + STAP_PROBE12(test_prov, twelve, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78);
>> +}
>> +EOF
>> +
>> +${CC} ${CFLAGS} -o test test.c
>> +if [ $? -ne 0 ]; then
>> + echo "failed to compile test.c" >& 2
>> + exit 1
>> +fi
>> +
>> +$dtrace -c ./test -qs /dev/stdin <<EOF
>> +test_prov\$target:::zero
>> +{
>> + printf("%s:%s:%s\n", probemod, probefunc, probename);
>> +}
>> +
>> +test_prov\$target:::one
>> +{
>> + printf("%s:%s:%s:%li\n", probemod, probefunc, probename, arg0);
>> +}
>> +
>> +test_prov\$target:::two
>> +{
>> + printf("%s:%s:%s:%li:%li\n", probemod, probefunc, probename, arg0, arg1);
>> +}
>> +
>> +test_prov\$target:::three
>> +{
>> + printf("%s:%s:%s:%li:%li:%li\n", probemod, probefunc, probename, arg0, arg1,
>> + arg2);
>> +}
>> +
>> +test_prov\$target:::four
>> +{
>> + printf("%s:%s:%s:%li:%li:%li:%li\n", probemod, probefunc, probename, arg0, arg1,
>> + arg2, arg3);
>> +}
>> +
>> +test_prov\$target:::five
>> +{
>> + printf("%s:%s:%s:%li:%li:%li:%li:%li\n", probemod, probefunc, probename,
>> + arg0, arg1, arg2, arg3, arg4);
>> +}
>> +
>> +test_prov\$target:::six
>> +{
>> + printf("%s:%s:%s:%li:%li:%li:%li:%li:%li\n", probemod, probefunc, probename,
>> + arg0, arg1, arg2, arg3, arg4, arg5);
>> +}
>> +
>> +test_prov\$target:::seven
>> +{
>> + printf("%s:%s:%s:%li:%li:%li:%li:%li:%li:%li\n", probemod, probefunc, probename,
>> + arg0, arg1, arg2, arg3, arg4, arg5, arg6);
>> +}
>> +
>> +test_prov\$target:::eight
>> +{
>> + printf("%s:%s:%s:%li:%li:%li:%li:%li:%li:%li:%li\n", probemod, probefunc, probename,
>> + arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
>> +}
>> +
>> +test_prov\$target:::nine
>> +{
>> + printf("%s:%s:%s:%li:%li:%li:%li:%li:%li:%li:%li:%li\n", probemod, probefunc, probename,
>> + arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
>> +}
>> +
>> +test_prov\$target:::ten,
>> +test_prov\$target:::eleven,
>> +test_prov\$target:::twelve
>> +{
>> + printf("%s:%s:%s:%li:%li:%li:%li:%li:%li:%li:%li:%li:%li\n", probemod, probefunc, probename,
>> + arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
>> +}
>> +EOF
>> +status=$?
>> +
>> +exit $status
>> --
>> 2.39.3
>>
More information about the DTrace-devel
mailing list