changeset: 78561:e4fe1daef9f7 branch: 2.7 parent: 78555:4c86a860e3d2 user: Richard Oudkerk date: Tue Aug 14 11:41:19 2012 +0100 files: Lib/multiprocessing/forking.py Lib/test/mp_fork_bomb.py Lib/test/test_multiprocessing.py Misc/NEWS description: Issue #15646: Prevent equivalent of a fork bomb when using multiprocessing on Windows without the "if __name__ == '__main__'" idiom. diff -r 4c86a860e3d2 -r e4fe1daef9f7 Lib/multiprocessing/forking.py --- a/Lib/multiprocessing/forking.py Mon Aug 13 22:04:30 2012 -0400 +++ b/Lib/multiprocessing/forking.py Tue Aug 14 11:41:19 2012 +0100 @@ -336,7 +336,7 @@ ''' Returns prefix of command line used for spawning a child process ''' - if process.current_process()._identity==() and is_forking(sys.argv): + if getattr(process.current_process(), '_inheriting', False): raise RuntimeError(''' Attempt to start a new process before the current process has finished its bootstrapping phase. diff -r 4c86a860e3d2 -r e4fe1daef9f7 Lib/test/mp_fork_bomb.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/test/mp_fork_bomb.py Tue Aug 14 11:41:19 2012 +0100 @@ -0,0 +1,16 @@ +import multiprocessing + +def foo(conn): + conn.send("123") + +# Because "if __name__ == '__main__'" is missing this will not work +# correctly on Windows. However, we should get a RuntimeError rather +# than the Windows equivalent of a fork bomb. + +r, w = multiprocessing.Pipe(False) +p = multiprocessing.Process(target=foo, args=(w,)) +p.start() +w.close() +print(r.recv()) +r.close() +p.join() diff -r 4c86a860e3d2 -r e4fe1daef9f7 Lib/test/test_multiprocessing.py --- a/Lib/test/test_multiprocessing.py Mon Aug 13 22:04:30 2012 -0400 +++ b/Lib/test/test_multiprocessing.py Tue Aug 14 11:41:19 2012 +0100 @@ -16,6 +16,7 @@ import random import logging import errno +import test.script_helper from test import test_support from StringIO import StringIO _multiprocessing = test_support.import_module('_multiprocessing') @@ -2349,8 +2350,28 @@ finally: socket.setdefaulttimeout(old_timeout) +# +# Test what happens with no "if __name__ == '__main__'" +# + +class TestNoForkBomb(unittest.TestCase): + def test_noforkbomb(self): + name = os.path.join(os.path.dirname(__file__), 'mp_fork_bomb.py') + if WIN32: + rc, out, err = test.script_helper.assert_python_failure(name) + self.assertEqual('', out.decode('ascii')) + self.assertIn('RuntimeError', err.decode('ascii')) + else: + rc, out, err = test.script_helper.assert_python_ok(name) + self.assertEqual('123', out.decode('ascii').rstrip()) + self.assertEqual('', err.decode('ascii')) + +# +# +# + testcases_other = [OtherTest, TestInvalidHandle, TestInitializers, - TestStdinBadfiledescriptor, TestTimeouts] + TestStdinBadfiledescriptor, TestTimeouts, TestNoForkBomb] # # diff -r 4c86a860e3d2 -r e4fe1daef9f7 Misc/NEWS --- a/Misc/NEWS Mon Aug 13 22:04:30 2012 -0400 +++ b/Misc/NEWS Tue Aug 14 11:41:19 2012 +0100 @@ -92,6 +92,10 @@ Library ------- +- Issue #15646: Prevent equivalent of a fork bomb when using + multiprocessing on Windows without the "if __name__ == '__main__'" + idiom. + - Issue #15567: Fix NameError when running threading._test - Issue #15424: Add a __sizeof__ implementation for array objects.

AltStyle によって変換されたページ (->オリジナル) /