gh-98894: Fix dtrace tests in shared builds - #153372
Conversation
|
cc @vstinner |
Generate SystemTap probe definitions targeting libpython for shared builds and use centralized USDT probe object discovery for readelf and BPFTrace.
|
Rebased to fix conflicts |
|
Python configured with: Without the change, I get: |
|
The systemtap tests require the same kernel-devel package as the running kernel, if it's not there the test will be skipped. |
|
I tested again the change. Python built with Without the change: With the change: 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. |
| PROBE_PLACEHOLDER = "@PYTHON_SYSTEMTAP_PROBE@" | ||
|
|
||
| @staticmethod | ||
| def _quote_systemtap_string(value): |
There was a problem hiding this comment.
There is no need to make the 3 added methods as private: you can remove the "_" prefix.
| executable = self._quote_systemtap_string(sys.executable) | ||
| probe_binary = get_probe_binary() | ||
| if probe_binary != sys.executable: | ||
| probe_binary = self._quote_systemtap_string(probe_binary) | ||
| return f'process("{executable}").library("{probe_binary}").mark' | ||
| return f'process("{executable}").mark' |
There was a problem hiding this comment.
| executable = self._quote_systemtap_string(sys.executable) | |
| probe_binary = get_probe_binary() | |
| if probe_binary != sys.executable: | |
| probe_binary = self._quote_systemtap_string(probe_binary) | |
| return f'process("{executable}").library("{probe_binary}").mark' | |
| return f'process("{executable}").mark' | |
| executable = self._quote_systemtap_string(sys.executable) | |
| probe_binary = get_probe_binary() | |
| if probe_binary == sys.executable: | |
| return f'process("{executable}").mark' | |
| # Python built with --enable-shared | |
| probe_binary = self._quote_systemtap_string(probe_binary) | |
| return f'process("{executable}").library("{probe_binary}").mark' |
| def _render_script(self, script_file): | ||
| with open(script_file) as script: | ||
| return script.read().replace( | ||
| self.PROBE_PLACEHOLDER, self._python_probe() | ||
| ) |
There was a problem hiding this comment.
| def _render_script(self, script_file): | |
| with open(script_file) as script: | |
| return script.read().replace( | |
| self.PROBE_PLACEHOLDER, self._python_probe() | |
| ) | |
| def _render_script(self, filename): | |
| with open(filename) as fp: | |
| script = fp.read() | |
| return script.replace(self.PROBE_PLACEHOLDER, self._python_probe()) |
| check_returncode=check_returncode, | ||
| ) | ||
| finally: | ||
| os.unlink(generated_script_file) |
There was a problem hiding this comment.
Please add from test.support import os_helper at the top, and replace this line with:
| os.unlink(generated_script_file) | |
| os_helper.unlink(generated_script_file) |
os_helper.unlink() tries harder to remove a file :-)
| return binary | ||
|
|
||
|
|
||
| def truncate_output(output, *, max_lines=3, max_chars=500): |
There was a problem hiding this comment.
This PR only changes many functions. I would prefer to revert this truncate_output() change (remove the function, restore old code).
I'm not convinced that truncating the output is a good thing. On our CI, it's usually hard to reproduce locally a failure, and so we need to collect as much data as we want when an error occurs. I would prefer not truncating the output.
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).