[Python-checkins] bpo-34658: Fix rare subprocess prexec_fn fork error. (GH-9255)

Miss Islington (bot) webhook-mailer at python.org
Thu Sep 13 13:11:03 EDT 2018


https://github.com/python/cpython/commit/b2ff9a9f9298761985aa85aa3f42421ce6effb9e
commit: b2ff9a9f9298761985aa85aa3f42421ce6effb9e
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2018-09-13T10:11:00-07:00
summary:

bpo-34658: Fix rare subprocess prexec_fn fork error. (GH-9255)


[bpo-34658](https://www.bugs.python.org/issue34658): Fix a rare interpreter unhandled exception state SystemError only
seen when using subprocess with a preexec_fn while an after_parent handler has
been registered with os.register_at_fork and the fork system call fails.

https://bugs.python.org/issue34658
(cherry picked from commit a20b6adb5a5880fd22c099961eb9f9787739cefe)

Co-authored-by: Gregory P. Smith <greg at krypto.org>

files:
A Misc/NEWS.d/next/Library/2018-09-13-03-59-43.bpo-34658.ykZ-ia.rst
M Modules/_posixsubprocess.c

diff --git a/Misc/NEWS.d/next/Library/2018-09-13-03-59-43.bpo-34658.ykZ-ia.rst b/Misc/NEWS.d/next/Library/2018-09-13-03-59-43.bpo-34658.ykZ-ia.rst
new file mode 100644
index 000000000000..35375a088300
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-09-13-03-59-43.bpo-34658.ykZ-ia.rst
@@ -0,0 +1,3 @@
+Fix a rare interpreter unhandled exception state SystemError only seen when
+using subprocess with a preexec_fn while an after_parent handler has been
+registered with os.register_at_fork and the fork system call fails.
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c
index aeb10f9ecfe4..dd69b9eb1ff6 100644
--- a/Modules/_posixsubprocess.c
+++ b/Modules/_posixsubprocess.c
@@ -564,6 +564,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
     char *const *exec_array, *const *argv = NULL, *const *envp = NULL;
     Py_ssize_t arg_num;
     int need_after_fork = 0;
+    int saved_errno = 0;
 
     if (!PyArg_ParseTuple(
             args, "OOpO!OOiiiiiiiiiiO:fork_exec",
@@ -700,14 +701,14 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
         _exit(255);
         return NULL;  /* Dead code to avoid a potential compiler warning. */
     }
-    Py_XDECREF(cwd_obj2);
-
+    /* Parent (original) process */
     if (pid == -1) {
-        /* Capture the errno exception before errno can be clobbered. */
-        PyErr_SetFromErrno(PyExc_OSError);
+        /* Capture errno for the exception. */
+        saved_errno = errno;
     }
 
-    /* Parent process */
+    Py_XDECREF(cwd_obj2);
+
     if (need_after_fork)
         PyOS_AfterFork_Parent();
     if (envp)
@@ -723,8 +724,13 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
     Py_XDECREF(preexec_fn_args_tuple);
     Py_XDECREF(gc_module);
 
-    if (pid == -1)
-        return NULL;  /* fork() failed.  Exception set earlier. */
+    if (pid == -1) {
+        errno = saved_errno;
+        /* We can't call this above as PyOS_AfterFork_Parent() calls back
+         * into Python code which would see the unreturned error. */
+        PyErr_SetFromErrno(PyExc_OSError);
+        return NULL;  /* fork() failed. */
+    }
 
     return PyLong_FromPid(pid);
 



More information about the Python-checkins mailing list