[Python-checkins] cpython (merge 3.5 -> 3.6): Issue #28779: multiprocessing.set_forkserver_preload() would crash the

antoine.pitrou python-checkins at python.org
Sat Dec 10 11:22:10 EST 2016


https://hg.python.org/cpython/rev/f3b9fd41b5cb
changeset:   105575:f3b9fd41b5cb
branch:      3.6
parent:      105572:f9e0c864157c
parent:      105574:1a955981b263
user:        Antoine Pitrou <solipsis at pitrou.net>
date:        Sat Dec 10 17:16:17 2016 +0100
summary:
  Issue #28779: multiprocessing.set_forkserver_preload() would crash the forkserver process if a preloaded module instantiated some multiprocessing objects such as locks.

files:
  Lib/multiprocessing/context.py    |   2 +-
  Lib/multiprocessing/spawn.py      |   2 +-
  Lib/test/_test_multiprocessing.py |  13 +++++++++++++
  Lib/test/mp_preload.py            |  18 ++++++++++++++++++
  Misc/NEWS                         |   4 ++++
  5 files changed, 37 insertions(+), 2 deletions(-)


diff --git a/Lib/multiprocessing/context.py b/Lib/multiprocessing/context.py
--- a/Lib/multiprocessing/context.py
+++ b/Lib/multiprocessing/context.py
@@ -196,7 +196,7 @@
     def get_start_method(self, allow_none=False):
         return self._name
 
-    def set_start_method(self, method=None):
+    def set_start_method(self, method, force=False):
         raise ValueError('cannot set start method of concrete context')
 
     @property
diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py
--- a/Lib/multiprocessing/spawn.py
+++ b/Lib/multiprocessing/spawn.py
@@ -217,7 +217,7 @@
         process.ORIGINAL_DIR = data['orig_dir']
 
     if 'start_method' in data:
-        set_start_method(data['start_method'])
+        set_start_method(data['start_method'], force=True)
 
     if 'init_main_from_name' in data:
         _fixup_main_from_name(data['init_main_from_name'])
diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py
--- a/Lib/test/_test_multiprocessing.py
+++ b/Lib/test/_test_multiprocessing.py
@@ -3818,6 +3818,19 @@
             self.assertTrue(methods == ['fork', 'spawn'] or
                             methods == ['fork', 'spawn', 'forkserver'])
 
+    def test_preload_resources(self):
+        if multiprocessing.get_start_method() != 'forkserver':
+            self.skipTest("test only relevant for 'forkserver' method")
+        name = os.path.join(os.path.dirname(__file__), 'mp_preload.py')
+        rc, out, err = test.support.script_helper.assert_python_ok(name)
+        out = out.decode()
+        err = err.decode()
+        if out.rstrip() != 'ok' or err != '':
+            print(out)
+            print(err)
+            self.fail("failed spawning forkserver or grandchild")
+
+
 #
 # Check that killing process does not leak named semaphores
 #
diff --git a/Lib/test/mp_preload.py b/Lib/test/mp_preload.py
new file mode 100644
--- /dev/null
+++ b/Lib/test/mp_preload.py
@@ -0,0 +1,18 @@
+import multiprocessing
+
+multiprocessing.Lock()
+
+
+def f():
+    print("ok")
+
+
+if __name__ == "__main__":
+    ctx = multiprocessing.get_context("forkserver")
+    modname = "test.mp_preload"
+    # Make sure it's importable
+    __import__(modname)
+    ctx.set_forkserver_preload([modname])
+    proc = ctx.Process(target=f)
+    proc.start()
+    proc.join()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -22,6 +22,10 @@
 Library
 -------
 
+- Issue #28779: multiprocessing.set_forkserver_preload() would crash the
+  forkserver process if a preloaded module instantiated some
+  multiprocessing objects such as locks.
+
 - Issue #28847: dbm.dumb now supports reading read-only files and no longer
   writes the index file when it is not changed.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list