Skip to content

gh-98894: Fix dtrace tests in shared builds - #153372

Merged
vstinner merged 4 commits into
python:mainfrom
stratakis:shared_probes
Aug 7, 2026
Merged

gh-98894: Fix dtrace tests in shared builds#153372
vstinner merged 4 commits into
python:mainfrom
stratakis:shared_probes

Conversation

@stratakis

@stratakisstratakis commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

When Python is configured with --with-dtrace and --enable-shared, its USDT probes are in libpython, not the executable. The SystemTap and BPFTrace backends in test_dtrace were searching the executable, causing the tests to fail or time out. This PR makes both backends target the object containing the probes. Static builds are unaffected.

On Fedora, this can be reproduced by running test_dtrace for BPFTrace as sudo and for SystemTap either as sudo or as a user in the stapusr and stapdev groups.

Also added a commit to truncate the output of the tools as it can be quite verbose when it errors out (you can inspect by running the same tests without sudo).

@stratakis

Copy link
Copy Markdown
ContributorAuthor

cc @vstinner

Generate SystemTap probe definitions targeting libpython for shared
builds and use centralized USDT probe object discovery for readelf
and BPFTrace.
@stratakis

Copy link
Copy Markdown
ContributorAuthor

Rebased to fix conflicts

@vstinner

Copy link
Copy Markdown
Member

Python configured with: ./configure --with-pydebug --with-dtrace --enable-shared.

Without the change, I get:

# LANG= LD_LIBRARY_PATH=$PWD ./python -m test -v test_dtrace == CPython 3.16.0a0 (heads/main:ed716551e13, Jul 13 2026, 07:59:05) [GCC 16.1.1 20260515 (Red Hat 16.1.1-2)]
== Linux-7.0.12-201.fc44.x86_64-x86_64-with-glibc2.43 little-endian
== Python build: debug shared dtrace
== cwd: /home/vstinner/python/main/build/test_python_worker_3188349æ
== CPU count: 10 (process) / 12 (system)
== encodings: locale=UTF-8 FS=utf-8
== resources: all test resources are disabled, use -u option to unskip tests
Using random seed: 3520453529
0:00:00 load avg: 2.02 mem: 22.5 MiB Run 1 test sequentially in a single process
0:00:00 load avg: 2.02 mem: 22.5 MiB [1/1] test_dtrace
setUpClass (test.test_dtrace.BPFTraceNormalTests) ... skipped 'bpftrace timed out during usability check'
setUpClass (test.test_dtrace.BPFTraceOptimizedTests) ... skipped 'bpftrace timed out during usability check'
test_filter_probe_rows_ignores_warnings (test.test_dtrace.BPFTraceOutputTests.test_filter_probe_rows_ignores_warnings) ... ok
readelf version: 2.46
test_check_probes (test.test_dtrace.CheckDtraceProbes.test_check_probes) ... ok
test_missing_probes (test.test_dtrace.CheckDtraceProbes.test_missing_probes) ... expected failure
skipped 'dtrace(1) failed: /usr/sbin/dtrace invalid option -q\nUsage /usr/sbin/dtrace [--help] [-h | -G] [-C [-I<Path>]] -s File.d [-o <File>]'
setUpClass (test.test_dtrace.DTraceOptimizedTests) ... skipped 'dtrace(1) failed: /usr/sbin/dtrace invalid option -q\nUsage /usr/sbin/dtrace [--help] [-h | -G] [-C [-I<Path>]] -s File.d [-o <File>]'
setUpClass (test.test_dtrace.SystemTapNormalTests) ... skipped 'stap(1) failed: parse error: expected literal string or number\n saw: operator \'*\' at /usr/share/systemtap/tapset/libvirt_probes-64.stp:204:3\n source: *cert = user_string($arg4);\n ^\n\n1 parse error.\nstap_69e06176e3befa287a4f6741352860fa_990_src.c:12:10: fatal error: runtime_defines.h: No such file or directory\n 12 | #include "runtime_defines.h"\n | ^~~~~~~~~~~~~~~~~~~\ncompilation terminated.\nmake[2]: *** [/usr/src/kernels/7.0.12-201.fc44.x86_64/scripts/Makefile.build:289: stap_69e06176e3befa287a4f6741352860fa_990_src.o] Error 1\nmake[2]: *** Waiting for unfinished jobs....\nstap_symbols.c:3:10: fatal error: sym.h: No such file or directory\n 3 | #include <sym.h>\n | ^~~~~~~\ncompilation terminated.\nmake[2]: *** [/usr/src/kernels/7.0.12-201.fc44.x86_64/scripts/Makefile.build:289: stap_symbols.o] Error 1\nmake[1]: *** [/usr/src/kernels/7.0.12-201.fc44.x86_64/Makefile:2140: .] Error 2\nmake: *** [Makefile:248: __sub-make] Error 2\nWARNING: kbuild exited with status: 2\nPass 4: compilation failed. [man error::pass4]\nKernel version 7.0.12 is outside tested range 3.10 ... 7.0'
setUpClass (test.test_dtrace.SystemTapOptimizedTests) ... skipped 'stap(1) failed: parse error: expected literal string or number\n saw: operator \'*\' at /usr/share/systemtap/tapset/libvirt_probes-64.stp:204:3\n source: *cert = user_string($arg4);\n ^\n\n1 parse error.\nstap_69e06176e3befa287a4f6741352860fa_990_src.c:12:10: fatal error: runtime_defines.h: No such file or directory\n 12 | #include "runtime_defines.h"\n | ^~~~~~~~~~~~~~~~~~~\ncompilation terminated.\nmake[2]: *** [/usr/src/kernels/7.0.12-201.fc44.x86_64/scripts/Makefile.build:289: stap_69e06176e3befa287a4f6741352860fa_990_src.o] Error 1\nmake[2]: *** Waiting for unfinished jobs....\nstap_symbols.c:3:10: fatal error: sym.h: No such file or directory\n 3 | #include <sym.h>\n | ^~~~~~~\ncompilation terminated.\nmake[2]: *** [/usr/src/kernels/7.0.12-201.fc44.x86_64/scripts/Makefile.build:289: stap_symbols.o] Error 1\nmake[1]: *** [/usr/src/kernels/7.0.12-201.fc44.x86_64/Makefile:2140: .] Error 2\nmake: *** [Makefile:248: __sub-make] Error 2\nWARNING: kbuild exited with status: 2\nPass 4: compilation failed. [man error::pass4]\nKernel version 7.0.12 is outside tested range 3.10 ... 7.0'
----------------------------------------------------------------------
Ran 3 tests in 24.814s
OK (skipped=6, expected failures=1)
0:00:24 load avg: 1.75 mem: 22.9 MiB [1/1] test_dtrace passed
== Tests result: SUCCESS ==
1 test OK.
Total duration: 24.9 sec
Total tests: run=3 skipped=6
Total test files: run=1/1
Result: SUCCESS

@stratakis

Copy link
Copy Markdown
ContributorAuthor

The systemtap tests require the same kernel-devel package as the running kernel, if it's not there the test will be skipped.

@vstinner

Copy link
Copy Markdown
Member

I tested again the change. Python built with ./configure --with-pydebug --with-dtrace --enable-shared and test_dtrace runs as root.

Without the change:

setUpClass (test.test_dtrace.BPFTraceNormalTests) ... skipped 'bpftrace timed out during usability check'
setUpClass (test.test_dtrace.BPFTraceOptimizedTests) ... skipped 'bpftrace timed out during usability check'
test_filter_probe_rows_ignores_warnings (test.test_dtrace.BPFTraceOutputTests.test_filter_probe_rows_ignores_warnings) ... ok
readelf version: 2.46
test_check_probes (test.test_dtrace.CheckDtraceProbes.test_check_probes) ... ok
test_missing_probes (test.test_dtrace.CheckDtraceProbes.test_missing_probes) ... expected failure
skipped 'dtrace(1) failed: /usr/sbin/dtrace invalid option -q\nUsage /usr/sbin/dtrace [--help] [-h | -G] [-C [-I<Path>]] -s File.d [-o <File>]'
setUpClass (test.test_dtrace.DTraceOptimizedTests) ... skipped 'dtrace(1) failed: /usr/sbin/dtrace invalid option -q\nUsage /usr/sbin/dtrace [--help] [-h | -G] [-C [-I<Path>]] -s File.d [-o <File>]'
setUpClass (test.test_dtrace.SystemTapNormalTests) ... skipped 'stap(1) failed: parse error: expected literal string or number\n saw: operator \'*\' at /usr/share/systemtap/tapset/libvirt_probes-64.stp:204:3\n source: *cert = user_string($arg4);\n ^\n\n1 parse error.\nstap_ad00f0008fef1242c8a51840ffeb6b1e_983_src.c:12:10: fatal error: runtime_defines.h: No such file or directory\n 12 | #include "runtime_defines.h"\n | ^~~~~~~~~~~~~~~~~~~\ncompilation terminated.\nmake[2]: *** [/usr/src/kernels/7.1.4-204.fc44.x86_64/scripts/Makefile.build:289: stap_ad00f0008fef1242c8a51840ffeb6b1e_983_src.o] Error 1\nmake[2]: *** Waiting for unfinished jobs....\nstap_symbols.c:3:10: fatal error: sym.h: No such file or directory\n 3 | #include <sym.h>\n | ^~~~~~~\ncompilation terminated.\nmake[2]: *** [/usr/src/kernels/7.1.4-204.fc44.x86_64/scripts/Makefile.build:289: stap_symbols.o] Error 1\nmake[1]: *** [/usr/src/kernels/7.1.4-204.fc44.x86_64/Makefile:2192: .] Error 2\nmake: *** [Makefile:248: __sub-make] Error 2\nWARNING: kbuild exited with status: 2\nPass 4: compilation failed. [man error::pass4]\nKernel version 7.1.4 is outside tested range 3.10 ... 7.0'
setUpClass (test.test_dtrace.SystemTapOptimizedTests) ... skipped 'stap(1) failed: parse error: expected literal string or number\n saw: operator \'*\' at /usr/share/systemtap/tapset/libvirt_probes-64.stp:204:3\n source: *cert = user_string($arg4);\n ^\n\n1 parse error.\nstap_ad00f0008fef1242c8a51840ffeb6b1e_983_src.c:12:10: fatal error: runtime_defines.h: No such file or directory\n 12 | #include "runtime_defines.h"\n | ^~~~~~~~~~~~~~~~~~~\ncompilation terminated.\nmake[2]: *** [/usr/src/kernels/7.1.4-204.fc44.x86_64/scripts/Makefile.build:289: stap_ad00f0008fef1242c8a51840ffeb6b1e_983_src.o] Error 1\nmake[2]: *** Waiting for unfinished jobs....\nstap_symbols.c:3:10: fatal error: sym.h: No such file or directory\n 3 | #include <sym.h>\n | ^~~~~~~\ncompilation terminated.\nmake[2]: *** [/usr/src/kernels/7.1.4-204.fc44.x86_64/scripts/Makefile.build:289: stap_symbols.o] Error 1\nmake[1]: *** [/usr/src/kernels/7.1.4-204.fc44.x86_64/Makefile:2192: .] Error 2\nmake: *** [Makefile:248: __sub-make] Error 2\nWARNING: kbuild exited with status: 2\nPass 4: compilation failed. [man error::pass4]\nKernel version 7.1.4 is outside tested range 3.10 ... 7.0'
----------------------------------------------------------------------
Ran 3 tests in 24.678s
OK (skipped=6, expected failures=1)
...
Total tests: run=3 skipped=6
Total test files: run=1/1

With the change:

test_function_entry_return (test.test_dtrace.BPFTraceNormalTests.test_function_entry_return) ... ok
test_gc (test.test_dtrace.BPFTraceNormalTests.test_gc) ... ok
test_verify_call_opcodes (test.test_dtrace.BPFTraceNormalTests.test_verify_call_opcodes)
Ensure our call stack test hits all function call opcodes ... ok
test_function_entry_return (test.test_dtrace.BPFTraceOptimizedTests.test_function_entry_return) ... ok
test_gc (test.test_dtrace.BPFTraceOptimizedTests.test_gc) ... ok
test_verify_call_opcodes (test.test_dtrace.BPFTraceOptimizedTests.test_verify_call_opcodes)
Ensure our call stack test hits all function call opcodes ... ok
test_filter_probe_rows_ignores_warnings (test.test_dtrace.BPFTraceOutputTests.test_filter_probe_rows_ignores_warnings) ... ok
readelf version: 2.46
test_check_probes (test.test_dtrace.CheckDtraceProbes.test_check_probes) ... ok
test_missing_probes (test.test_dtrace.CheckDtraceProbes.test_missing_probes) ... expected failure
skipped 'dtrace(1) failed: /usr/sbin/dtrace invalid option -q; Usage /usr/sbin/dtrace [--help] [-h | -G] [-C [-I<Path>]] -s File.d [-o <File>]'
setUpClass (test.test_dtrace.DTraceOptimizedTests) ... skipped 'dtrace(1) failed: /usr/sbin/dtrace invalid option -q; Usage /usr/sbin/dtrace [--help] [-h | -G] [-C [-I<Path>]] -s File.d [-o <File>]'
setUpClass (test.test_dtrace.SystemTapNormalTests) ... skipped "stap(1) failed: parse error: expected literal string or number; saw: operator '*' at /usr/share/systemtap/tapset/libvirt_probes-64.stp:204:3; source: *cert = user_string($arg4);; ... (18 lines omitted)"
setUpClass (test.test_dtrace.SystemTapOptimizedTests) ... skipped "stap(1) failed: parse error: expected literal string or number; saw: operator '*' at /usr/share/systemtap/tapset/libvirt_probes-64.stp:204:3; source: *cert = user_string($arg4);; ... (18 lines omitted)"
----------------------------------------------------------------------
Ran 9 tests in 7.410s
OK (skipped=4, expected failures=1)
...
Total tests: run=9 skipped=4
Total test files: run=1/1

So we get: "Total tests: run=3 skipped=6" => "Total tests: run=9 skipped=4". 6 more tests are run thanks to the change.

With the change, BPFTraceNormalTests and BPFTraceOptimizedTests tests are run.

Comment threadLib/test/test_dtrace.py Outdated
Comment threadLib/test/test_dtrace.py Outdated
Comment threadLib/test/test_dtrace.py Outdated
Comment threadLib/test/test_dtrace.py Outdated
Comment threadLib/test/test_dtrace.py Outdated
@vstinner
vstinner enabled auto-merge (squash) August 7, 2026 14:12
@vstinner
vstinner merged commit 298bef3 into python:mainAug 7, 2026
48 of 49 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@stratakis@vstinner