summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-09-18 06:29:25 (GMT)
committerGitHub <noreply@github.com>2019-09-18 06:29:25 (GMT)
commitda57599af51c602b015b6880123fef6eccdabcf5 (patch)
treeb57a79451276520b2372b62142b41405058dfd92
parent272d0d017aef585acf84bb0af99a90a2a8582b2c (diff)
downloadcpython-da57599af51c602b015b6880123fef6eccdabcf5.zip
cpython-da57599af51c602b015b6880123fef6eccdabcf5.tar.gz
cpython-da57599af51c602b015b6880123fef6eccdabcf5.tar.bz2
bpo-38203: regrtest: put a 2 min timeout on Python exit (GH-16250)
-rw-r--r--Lib/test/libregrtest/main.py34
1 files changed, 24 insertions, 10 deletions
diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py
index 3cfbb40..47c6012 100644
--- a/Lib/test/libregrtest/main.py
+++ b/Lib/test/libregrtest/main.py
@@ -22,6 +22,12 @@ from test.libregrtest.utils import removepy, count, format_duration, printlist
from test import support
+# bpo-38203: Maximum delay in seconds to exit Python (call Py_Finalize()).
+# Used to protect against threading._shutdown() hang.
+# Must be smaller than buildbot "1200 seconds without output" limit.
+EXIT_TIMEOUT = 120.0
+
+
class Regrtest:
"""Execute a test suite.
@@ -616,16 +622,24 @@ class Regrtest:
test_cwd = self.create_temp_dir()
- # Run the tests in a context manager that temporarily changes the CWD
- # to a temporary and writable directory. If it's not possible to
- # create or change the CWD, the original CWD will be used.
- # The original CWD is available from support.SAVEDCWD.
- with support.temp_cwd(test_cwd, quiet=True):
- # When using multiprocessing, worker processes will use test_cwd
- # as their parent temporary directory. So when the main process
- # exit, it removes also subdirectories of worker processes.
- self.ns.tempdir = test_cwd
- self._main(tests, kwargs)
+ try:
+ # Run the tests in a context manager that temporarily changes the CWD
+ # to a temporary and writable directory. If it's not possible to
+ # create or change the CWD, the original CWD will be used.
+ # The original CWD is available from support.SAVEDCWD.
+ with support.temp_cwd(test_cwd, quiet=True):
+ # When using multiprocessing, worker processes will use test_cwd
+ # as their parent temporary directory. So when the main process
+ # exit, it removes also subdirectories of worker processes.
+ self.ns.tempdir = test_cwd
+
+ self._main(tests, kwargs)
+ except SystemExit as exc:
+ # bpo-38203: Python can hang at exit in Py_Finalize(), especially
+ # on threading._shutdown() call: put a timeout
+ faulthandler.dump_traceback_later(EXIT_TIMEOUT, exit=True)
+
+ sys.exit(exc.code)
def getloadavg(self):
if self.win_load_tracker is not None: