summaryrefslogtreecommitdiff
path: root/Python
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2018-10-31 16:45:42 -0700
committerGitHub <noreply@github.com>2018-10-31 16:45:42 -0700
commit192c54713b4c67a8d14b2d98056771feba40ca37 (patch)
treebd818ad7e8fbaf8331cfd6511640e622883a20fb /Python
parent71b6c1af727fbe13525fb734568057d78cea33f3 (diff)
downloadcpython-git-192c54713b4c67a8d14b2d98056771feba40ca37.tar.gz
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. (cherry picked from commit 3a228ab17c2a9cffd1a2f15f30d6209768de20a6) Co-authored-by: Victor Stinner <vstinner@redhat.com>
Diffstat (limited to 'Python')
-rw-r--r--Python/pylifecycle.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index c01b21ffeb..86f95de833 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -2015,12 +2015,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 */
@@ -2125,9 +2119,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);
}
@@ -2138,7 +2153,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();
}