diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2014-10-05 15:25:19 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2014-10-05 15:25:19 (GMT) |
commit | 8f437aac068e13fe8418bb0374baf4395e7b4994 (patch) | |
tree | 498dcc48cfcc4e1472dadb9c1552188db929c3c1 /Modules | |
parent | 340c749a3a091f14c7701b66a05e864c8f95740a (diff) | |
download | cpython-8f437aac068e13fe8418bb0374baf4395e7b4994.zip cpython-8f437aac068e13fe8418bb0374baf4395e7b4994.tar.gz cpython-8f437aac068e13fe8418bb0374baf4395e7b4994.tar.bz2 |
Issue #22290: Fix error handling in the _posixsubprocess module.
* Don't call the garbage collector with an exception set: it causes an
assertion to fail in debug mode.
* Enhance also error handling if allocating an array for the executable list
failed.
* Add an unit test for 4 different errors in the _posixsubprocess module.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_posixsubprocess.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index f84cd26..a8c2be2 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -538,6 +538,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) int need_to_reenable_gc = 0; char *const *exec_array, *const *argv = NULL, *const *envp = NULL; Py_ssize_t arg_num; + int import_lock_held = 0; if (!PyArg_ParseTuple( args, "OOpOOOiiiiiiiiiiO:fork_exec", @@ -590,10 +591,8 @@ subprocess_fork_exec(PyObject* self, PyObject *args) } exec_array = _PySequence_BytesToCharpArray(executable_list); - if (!exec_array) { - Py_XDECREF(gc_module); - return NULL; - } + if (!exec_array) + goto cleanup; /* Convert args and env into appropriate arguments for exec() */ /* These conversions are done in the parent process to avoid allocating @@ -635,6 +634,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) if (!preexec_fn_args_tuple) goto cleanup; _PyImport_AcquireLock(); + import_lock_held = 1; } if (cwd_obj != Py_None) { @@ -682,6 +682,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) PyErr_SetString(PyExc_RuntimeError, "not holding the import lock"); } + import_lock_held = 0; /* Parent process */ if (envp) @@ -704,18 +705,25 @@ subprocess_fork_exec(PyObject* self, PyObject *args) return PyLong_FromPid(pid); cleanup: + if (import_lock_held) + _PyImport_ReleaseLock(); if (envp) _Py_FreeCharPArray(envp); if (argv) _Py_FreeCharPArray(argv); - _Py_FreeCharPArray(exec_array); + if (exec_array) + _Py_FreeCharPArray(exec_array); Py_XDECREF(converted_args); Py_XDECREF(fast_args); Py_XDECREF(preexec_fn_args_tuple); /* Reenable gc if it was disabled. */ - if (need_to_reenable_gc) + if (need_to_reenable_gc) { + PyObject *exctype, *val, *tb; + PyErr_Fetch(&exctype, &val, &tb); _enable_gc(gc_module); + PyErr_Restore(exctype, val, tb); + } Py_XDECREF(gc_module); return NULL; } |