https://github.com/python/cpython/commit/1785f4b35f899704df0be54cba3776906186b2b1
commit: 1785f4b35f899704df0be54cba3776906186b2b1
branch: main
author: stratakis <[email protected]>
committer: vstinner <[email protected]>
date: 2026-06-24T13:46:56Z
summary:
gh-151496: Use process groups in TraceBackend in test_dtrace (#152039)
Run the generic DTrace/SystemTap commands in a new process group and
terminate the whole group on timeout.
This prevents a forked tracer child from keeping stdout/stderr pipes
open after the direct tracer process is killed.
files:
M Lib/test/test_dtrace.py
diff --git a/Lib/test/test_dtrace.py b/Lib/test/test_dtrace.py
index 592f59d77f9221..3de87fc704d43e 100644
--- a/Lib/test/test_dtrace.py
+++ b/Lib/test/test_dtrace.py
@@ -75,10 +75,13 @@ class TraceBackend:
COMMAND_ARGS = []
def run_case(self, name, optimize_python=None):
- actual_output = normalize_trace_output(self.trace_python(
- script_file=abspath(name + self.EXTENSION),
- python_file=abspath(name + ".py"),
- optimize_python=optimize_python))
+ try:
+ actual_output = normalize_trace_output(self.trace_python(
+ script_file=abspath(name + self.EXTENSION),
+ python_file=abspath(name + ".py"),
+ optimize_python=optimize_python))
+ except subprocess.TimeoutExpired:
+ raise AssertionError(f"{self.COMMAND[0]} timed out")
with open(abspath(name + self.EXTENSION + ".expected")) as f:
expected_output = f.read().rstrip()
@@ -91,12 +94,17 @@ def generate_trace_command(self, script_file,
subcommand=None):
command += ["-c", subcommand]
return command
- def trace(self, script_file, subcommand=None):
+ def trace(self, script_file, subcommand=None, *, timeout=None):
command = self.generate_trace_command(script_file, subcommand)
- stdout, _ = subprocess.Popen(command,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- universal_newlines=True).communicate()
+ proc = create_process_group(command,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ universal_newlines=True)
+ try:
+ stdout, _ = proc.communicate(timeout=timeout)
+ except subprocess.TimeoutExpired:
+ kill_process_group(proc)
+ raise
return stdout
def trace_python(self, script_file, python_file, optimize_python=None):
@@ -104,12 +112,17 @@ def trace_python(self, script_file, python_file,
optimize_python=None):
if optimize_python:
python_flags.extend(["-O"] * optimize_python)
subcommand = " ".join([sys.executable] + python_flags + [python_file])
- return self.trace(script_file, subcommand)
+ return self.trace(script_file, subcommand, timeout=60)
def assert_usable(self):
try:
- output = self.trace(abspath("assert_usable" + self.EXTENSION))
+ output = self.trace(abspath("assert_usable" + self.EXTENSION),
+ timeout=10)
output = output.strip()
+ except subprocess.TimeoutExpired:
+ raise unittest.SkipTest(
+ f"{self.COMMAND[0]} timed out during usability check"
+ )
except (FileNotFoundError, NotADirectoryError, PermissionError) as
fnfe:
output = str(fnfe)
if output != "probe: success":
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]