Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork34k
Description
Bug report
Bug description:
This is primarily motivated byshadow/shadow#3697. The shadow simulator runs unmodified Linux software in an emulated environment where time passes precisely and deterministically. We use it at the Tor project for experimentation and testing. More about shadow, including academic publications about and using it, can be found athttps://shadow.github.io/.
Popen.communicate passes the remaining time as a timeout to thepoll syscall (on Linux). Under shadow's default time model, thepoll syscall returns with a timeout afterexactly that amount of time has passed, and no more time will have passed when remaining time is calculated in thePopen._communicate loop. This means that the calculated remaining time will beexactly 0. Since the loop only terminates when strictly less than 0 time remains, the loop never terminates.
As a result, under shadow, the following python program never terminates:
importsubprocessasspp=sp.Popen(['sleep','1'],stdin=sp.PIPE,stdout=sp.PIPE,stderr=sp.PIPE)p.communicate(timeout=0.01)
I've locally verified that the following patch fixes the issue under shadow, and python's "make test" still passes:
diff --git a/Lib/subprocess.py b/Lib/subprocess.pyindex 4d5ab6fbff0..0dbc2d2e4e3 100644--- a/Lib/subprocess.py+++ b/Lib/subprocess.py@@ -2140,7 +2140,7 @@ def _communicate(self, input, endtime, orig_timeout): while selector.get_map(): timeout = self._remaining_time(endtime)- if timeout is not None and timeout < 0:+ if timeout is not None and timeout <= 0: self._check_timeout(endtime, orig_timeout, stdout, stderr, skip_check_and_raise=True)
Would you be amenable to a PR with this change?
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux