Skip to content

Commit 713b4bb

Browse files
bpo-40550: Fix time-of-check/time-of-action issue in subprocess.Popen.send_signal. (GH-20010)
send_signal() now swallows the exception if the process it thought was still alive winds up not to exist anymore (always a plausible race condition despite the checks). Co-authored-by: Gregory P. Smith <[email protected]> (cherry picked from commit 01a202a) Co-authored-by: Filipe Laíns <[email protected]>
1 parent c1bbca5 commit 713b4bb

File tree

3 files changed

+19
-1
lines changed

3 files changed

+19
-1
lines changed

Lib/subprocess.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2061,7 +2061,11 @@ def send_signal(self, sig):
20612061
# The race condition can still happen if the race condition
20622062
# described above happens between the returncode test
20632063
# and the kill() call.
2064-
os.kill(self.pid, sig)
2064+
try:
2065+
os.kill(self.pid, sig)
2066+
except ProcessLookupError:
2067+
# Supress the race condition error; bpo-40550.
2068+
pass
20652069

20662070
def terminate(self):
20672071
"""Terminate the process with SIGTERM

Lib/test/test_subprocess.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3160,6 +3160,19 @@ def test_send_signal_race(self):
31603160
# so Popen failed to read it and uses a default returncode instead.
31613161
self.assertIsNotNone(proc.returncode)
31623162

3163+
def test_send_signal_race2(self):
3164+
# bpo-40550: the process might exist between the returncode check and
3165+
# the kill operation
3166+
p = subprocess.Popen([sys.executable, '-c', 'exit(1)'])
3167+
3168+
# wait for process to exit
3169+
while not p.returncode:
3170+
p.poll()
3171+
3172+
with mock.patch.object(p, 'poll', new=lambda: None):
3173+
p.returncode = None
3174+
p.send_signal(signal.SIGTERM)
3175+
31633176
def test_communicate_repeated_call_after_stdout_close(self):
31643177
proc = subprocess.Popen([sys.executable, '-c',
31653178
'import os, time; os.close(1), time.sleep(2)'],
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix time-of-check/time-of-action issue in subprocess.Popen.send_signal.

0 commit comments

Comments
 (0)