Skip to content

Commit fe2551d

Browse files
committed
gh-157184: Scale the join() alarm in the multiprocessing kill tests
_kill_process() interrupts the join() of the killed child with SIGALRM so that a blocked waitpid() becomes a readable error instead of a hang, but the alarm has been a fixed 10 seconds since 2013. On a build slow enough that reaping the child legitimately takes longer, it fires on a healthy run: seen on the UBSan CI job, where the alarm interrupted os.waitpid() itself. Use support.LONG_TIMEOUT, which is documented for detecting hangs and is scaled by regrtest for slow workers, as the same function already does for its event wait.
1 parent 024b6bc commit fe2551d

2 files changed

Lines changed: 10 additions & 1 deletion

File tree

Lib/test/_test_multiprocessing.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import time
1010
import io
1111
import itertools
12+
import math
1213
import sys
1314
import os
1415
import gc
@@ -624,11 +625,14 @@ def _kill_process(self, meth, target=None):
624625
if hasattr(signal, 'alarm'):
625626
# On the Gentoo buildbot waitpid() often seems to block forever.
626627
# We use alarm() to interrupt it if it blocks for too long.
628+
# The timeout only has to catch a hang, so use LONG_TIMEOUT:
629+
# a shorter one fires on a slow build where reaping the child
630+
# legitimately takes a while.
627631
def handler(*args):
628632
raise RuntimeError('join took too long: %s' % p)
629633
old_handler = signal.signal(signal.SIGALRM, handler)
630634
try:
631-
signal.alarm(10)
635+
signal.alarm(math.ceil(support.LONG_TIMEOUT))
632636
self.assertEqual(join(), None)
633637
finally:
634638
signal.alarm(0)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Fix the ``multiprocessing`` tests that kill a child process
2+
(``test_interrupt``, ``test_interrupt_no_handler``, ``test_terminate`` and
3+
``test_kill``) failing on slow builds: the alarm guarding the ``join()`` of
4+
the killed child used a fixed 10 second timeout, and now uses
5+
:data:`~test.support.LONG_TIMEOUT`, which regrtest scales.

0 commit comments

Comments
 (0)