fix: reliably kill shell process tree on Windows timeout#8822
fix: reliably kill shell process tree on Windows timeout#8822muhamedfazalps wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors local command execution in astrbot/core/computer/booters/local.py to use subprocess.Popen and proc.communicate instead of subprocess.run to handle timeouts manually. On Windows, it attempts to terminate the process tree using taskkill. The review feedback points out a redundant import of subprocess and notes that a failure in the taskkill command could mask the original TimeoutExpired exception, preventing proper process cleanup. It suggests wrapping the taskkill call in a try...except block to ensure robust cleanup.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| except subprocess.TimeoutExpired: | ||
| if sys.platform == "win32": | ||
| import subprocess as _sp | ||
| _sp.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], | ||
| capture_output=True, timeout=5) | ||
| else: | ||
| proc.kill() | ||
| proc.wait() | ||
| raise |
There was a problem hiding this comment.
There are two issues with the current implementation of the timeout handling on Windows:
- Redundant Import:
subprocessis already imported at the top of the file (line 7), soimport subprocess as _spis unnecessary. - Exception Masking: If
taskkillfails (e.g., if the executable is not found or if thetaskkillcommand itself times out), it will raise an exception. This will mask the originalTimeoutExpiredexception and preventproc.wait()from being called, potentially leaking resources. Wrapping thetaskkillcall in atry...exceptblock ensures that cleanup failures do not interfere with the propagation of the original timeout exception.
except subprocess.TimeoutExpired:
if sys.platform == "win32":
try:
subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=5)
except Exception:
pass
else:
proc.kill()
proc.wait()
raise
Fixes #8809
On Windows
subprocess.run(timeout=N)withshell=Trueonly kills cmd.exe, not the child process. Replaced with Popen+communicate + taskkill /F /T on Windows.https://buymeacoffee.com/muhamedfazalps
Summary by Sourcery
Improve local shell command execution to handle timeouts more robustly across platforms.
Bug Fixes:
Enhancements: