From c876b0cbeaad21aa45737140fcab18c9044eb6c6 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Thu, 13 Sep 2018 04:30:10 -0700 Subject: [PATCH 1/2] 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) manual edits to fix it up for 3.6 by gpshead. --- .../2018-09-13-03-59-43.bpo-34658.ykZ-ia.rst | 3 +++ Modules/_posixsubprocess.c | 20 ++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-09-13-03-59-43.bpo-34658.ykZ-ia.rst 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 00000000000000..35375a088300cc --- /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 fe0e554618aabb..cf880ad772ffc2 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -566,6 +566,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) #ifdef WITH_THREAD int import_lock_held = 0; #endif + int saved_errno = 0; if (!PyArg_ParseTuple( args, "OOpO!OOiiiiiiiiiiO:fork_exec", @@ -701,11 +702,10 @@ 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; } #ifdef WITH_THREAD if (preexec_fn != Py_None @@ -717,7 +717,8 @@ subprocess_fork_exec(PyObject* self, PyObject *args) import_lock_held = 0; #endif - /* Parent process */ + Py_XDECREF(cwd_obj2); + if (envp) _Py_FreeCharPArray(envp); if (argv) @@ -731,8 +732,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); From 1b5c3a13a6b290d5ba77665910b9060fb320442e Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Thu, 13 Sep 2018 17:25:53 -0700 Subject: [PATCH 2/2] [3.6] 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