Skip to content

Commit e9c07b5

Browse files
committed
Report which process terminated as cause of BPE
1 parent 98b4cd6 commit e9c07b5

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

Lib/concurrent/futures/process.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,15 @@ def _terminate_broken(self, cause):
477477
if cause is not None:
478478
bpe.__cause__ = _RemoteTraceback(
479479
f"\n'''\n{''.join(cause)}'''")
480+
else:
481+
# No cause known, so try to report some helpful info about
482+
# which process(es) terminated and with what exit code
483+
errors = []
484+
for p in self.processes.values():
485+
if p.exitcode: # Report any nonzero exit codes
486+
errors.append(f"Process {p.pid} terminated abruptly with exit code {p.exitcode}")
487+
if errors:
488+
bpe.__cause__ = _RemoteTraceback("\n".join(errors))
480489

481490
# Mark pending tasks as failed.
482491
for work_id, work_item in self.pending_work_items.items():

Lib/test/test_concurrent_futures/test_process_pool.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import ctypes
12
import os
23
import queue
34
import sys
@@ -106,6 +107,23 @@ def test_traceback(self):
106107
self.assertIn('raise RuntimeError(123) # some comment',
107108
f1.getvalue())
108109

110+
@staticmethod
111+
def _segfault():
112+
ctypes.string_at(0)
113+
114+
def test_traceback_when_child_process_segfaults(self):
115+
# gh-139462 enhancement - BrokenProcessPool exceptions
116+
# should describe which process terminated.
117+
future = self.executor.submit(self._segfault)
118+
with self.assertRaises(Exception) as cm:
119+
future.result()
120+
121+
bpe = cm.exception
122+
self.assertIs(type(bpe), BrokenProcessPool)
123+
cause = bpe.__cause__
124+
self.assertIs(type(cause), futures.process._RemoteTraceback)
125+
self.assertIn("terminated abruptly with exit code", cause.tb)
126+
109127
@warnings_helper.ignore_fork_in_thread_deprecation_warnings()
110128
@hashlib_helper.requires_hashdigest('md5')
111129
def test_ressources_gced_in_workers(self):

0 commit comments

Comments
 (0)