Skip to content

Commit 665bb1d

Browse files
committed
gh-151496: Use process groups in test_dtrace
Create a new process group to run bpftrace commands, so it's possible to kill also child processes on timeout.
1 parent 35ce2e5 commit 665bb1d

1 file changed

Lines changed: 25 additions & 4 deletions

File tree

Lib/test/test_dtrace.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import dis
22
import os.path
33
import re
4+
import signal
45
import subprocess
56
import sys
67
import sysconfig
@@ -50,6 +51,26 @@ def normalize_trace_output(output):
5051
)
5152

5253

54+
USE_PROCESS_GROUP = (hasattr(os, "setsid") and hasattr(os, "killpg"))
55+
56+
def create_process_group(*args, **kwargs):
57+
if USE_PROCESS_GROUP:
58+
kwargs['start_new_session'] = True
59+
return subprocess.Popen(*args, **kwargs)
60+
61+
def kill_process_group(proc):
62+
use_killpg = USE_PROCESS_GROUP
63+
if use_killpg:
64+
parent_sid = os.getsid(0)
65+
sid = os.getsid(proc.pid)
66+
use_killpg = (sid != parent_sid)
67+
68+
if use_killpg:
69+
os.killpg(proc.pid, signal.SIGKILL)
70+
else:
71+
proc.kill()
72+
73+
5374
class TraceBackend:
5475
EXTENSION = None
5576
COMMAND = None
@@ -205,15 +226,15 @@ def run_case(self, name, optimize_python=None):
205226
program = self.PROGRAMS[name].format(python=sys.executable)
206227

207228
try:
208-
proc = subprocess.Popen(
229+
proc = create_process_group(
209230
["bpftrace", "-e", program, "-c", " ".join(subcommand)],
210231
stdout=subprocess.PIPE,
211232
stderr=subprocess.PIPE,
212233
universal_newlines=True,
213234
)
214235
stdout, stderr = proc.communicate(timeout=60)
215236
except subprocess.TimeoutExpired:
216-
proc.kill()
237+
kill_process_group(proc)
217238
raise AssertionError("bpftrace timed out")
218239
except (FileNotFoundError, PermissionError) as e:
219240
raise unittest.SkipTest(f"bpftrace not available: {e}")
@@ -243,15 +264,15 @@ def assert_usable(self):
243264
# Check if bpftrace is available and can attach to USDT probes
244265
program = f'usdt:{sys.executable}:python:function__entry {{ printf("probe: success\\n"); exit(); }}'
245266
try:
246-
proc = subprocess.Popen(
267+
proc = create_process_group(
247268
["bpftrace", "-e", program, "-c", f"{sys.executable} -c pass"],
248269
stdout=subprocess.PIPE,
249270
stderr=subprocess.PIPE,
250271
universal_newlines=True,
251272
)
252273
stdout, stderr = proc.communicate(timeout=10)
253274
except subprocess.TimeoutExpired:
254-
proc.kill()
275+
kill_process_group(proc)
255276
proc.communicate() # Clean up
256277
raise unittest.SkipTest("bpftrace timed out during usability check")
257278
except OSError as e:

0 commit comments

Comments
 (0)