diff options
author | Victor Stinner <vstinner@redhat.com> | 2018-10-31 23:26:41 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-31 23:26:41 (GMT) |
commit | 3a228ab17c2a9cffd1a2f15f30d6209768de20a6 (patch) | |
tree | 9f976a1179349145541c093cb792e4ee93beecb8 /Python/pylifecycle.c | |
parent | 2be00d987d37682a55db67c298e82c405d01b868 (diff) | |
download | cpython-3a228ab17c2a9cffd1a2f15f30d6209768de20a6.zip cpython-3a228ab17c2a9cffd1a2f15f30d6209768de20a6.tar.gz cpython-3a228ab17c2a9cffd1a2f15f30d6209768de20a6.tar.bz2 |
bpo-26558: Fix Py_FatalError() with GIL released (GH-10267)
Don't call _Py_FatalError_PrintExc() nor flush_std_files() if the
current thread doesn't hold the GIL, or if the current thread
has no Python state thread.
Diffstat (limited to 'Python/pylifecycle.c')
-rw-r--r-- | Python/pylifecycle.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 78691a5..fab96fd 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1820,12 +1820,6 @@ _Py_FatalError_PrintExc(int fd) PyObject *exception, *v, *tb; int has_tb; - if (PyThreadState_GET() == NULL) { - /* The GIL is released: trying to acquire it is likely to deadlock, - just give up. */ - return 0; - } - PyErr_Fetch(&exception, &v, &tb); if (exception == NULL) { /* No current exception */ @@ -1930,9 +1924,30 @@ fatal_error(const char *prefix, const char *msg, int status) fputs("\n", stderr); fflush(stderr); /* it helps in Windows debug build */ - /* Print the exception (if an exception is set) with its traceback, - * or display the current Python stack. */ - if (!_Py_FatalError_PrintExc(fd)) { + /* Check if the current thread has a Python thread state + and holds the GIL */ + PyThreadState *tss_tstate = PyGILState_GetThisThreadState(); + if (tss_tstate != NULL) { + PyThreadState *tstate = PyThreadState_GET(); + if (tss_tstate != tstate) { + /* The Python thread does not hold the GIL */ + tss_tstate = NULL; + } + } + else { + /* Py_FatalError() has been called from a C thread + which has no Python thread state. */ + } + int has_tstate_and_gil = (tss_tstate != NULL); + + if (has_tstate_and_gil) { + /* If an exception is set, print the exception with its traceback */ + if (!_Py_FatalError_PrintExc(fd)) { + /* No exception is set, or an exception is set without traceback */ + _Py_FatalError_DumpTracebacks(fd); + } + } + else { _Py_FatalError_DumpTracebacks(fd); } @@ -1943,7 +1958,7 @@ fatal_error(const char *prefix, const char *msg, int status) _PyFaulthandler_Fini(); /* Check if the current Python thread hold the GIL */ - if (PyThreadState_GET() != NULL) { + if (has_tstate_and_gil) { /* Flush sys.stdout and sys.stderr */ flush_std_files(); } |