Avoid accidental fork bombs due to try/except (#51633) (#51636)

WorkerProcess exceptions could previously cause StrategyBase loop to
resume in every child. See ticket description.
pull/51705/head
dw 6 years ago committed by jctanner
parent e3006e8443
commit 30eea29373

@ -87,7 +87,40 @@ class WorkerProcess(multiprocessing.Process):
# set to /dev/null
self._new_stdin = os.devnull
def _hard_exit(self, e):
'''
There is no safe exception to return to higher level code that does not
risk an innocent try/except finding itself executing in the wrong
process. All code executing above WorkerProcess.run() on the stack
conceptually belongs to another program.
'''
try:
display.debug(u"WORKER HARD EXIT: %s" % to_text(e))
except BaseException:
# If the cause of the fault is IOError being generated by stdio,
# attempting to log a debug message may trigger another IOError.
# Try printing once then give up.
pass
os._exit(1)
def run(self):
'''
Wrap _run() to ensure no possibility an errant exception can cause
control to return to the StrategyBase task loop, or any other code
higher in the stack.
As multiprocessing in Python 2.x provides no protection, it is possible
a try/except added in far-away code can cause a crashed child process
to suddenly assume the role and prior state of its parent.
'''
try:
return self._run()
except BaseException as e:
self._hard_exit(e)
def _run(self):
'''
Called when the process is started. Pushes the result onto the
results queue. We also remove the host from the blocked hosts list, to

Loading…
Cancel
Save