@@ -1267,31 +1267,62 @@ initstdio(void)
12671267}
12681268
12691269
1270+ static void
1271+ _Py_FatalError_DumpTracebacks (int fd )
1272+ {
1273+ PyThreadState * tstate ;
1274+
1275+ #ifdef WITH_THREAD
1276+ /* PyGILState_GetThisThreadState() works even if the GIL was released */
1277+ tstate = PyGILState_GetThisThreadState ();
1278+ #else
1279+ tstate = PyThreadState_GET ();
1280+ #endif
1281+ if (tstate == NULL ) {
1282+ /* _Py_DumpTracebackThreads() requires the thread state to display
1283+ * frames */
1284+ return ;
1285+ }
1286+
1287+ fputc ('\n' , stderr );
1288+ fflush (stderr );
1289+
1290+ /* display the current Python stack */
1291+ _Py_DumpTracebackThreads (fd , tstate -> interp , tstate );
1292+ }
1293+
12701294/* Print the current exception (if an exception is set) with its traceback,
1271- * or display the current Python stack.
1272- *
1273- * Don't call PyErr_PrintEx() and the except hook, because Py_FatalError() is
1274- * called on catastrophic cases. */
1295+ or display the current Python stack.
12751296
1276- static void
1277- _Py_PrintFatalError (int fd )
1297+ Don't call PyErr_PrintEx() and the except hook, because Py_FatalError() is
1298+ called on catastrophic cases.
1299+
1300+ Return 1 if the traceback was displayed, 0 otherwise. */
1301+
1302+ static int
1303+ _Py_FatalError_PrintExc (int fd )
12781304{
12791305 PyObject * ferr , * res ;
12801306 PyObject * exception , * v , * tb ;
12811307 int has_tb ;
1282- PyThreadState * tstate ;
1308+
1309+ if (PyThreadState_GET () == NULL ) {
1310+ /* The GIL is released: trying to acquire it is likely to deadlock,
1311+ just give up. */
1312+ return 0 ;
1313+ }
12831314
12841315 PyErr_Fetch (& exception , & v , & tb );
12851316 if (exception == NULL ) {
12861317 /* No current exception */
1287- goto display_stack ;
1318+ return 0 ;
12881319 }
12891320
12901321 ferr = _PySys_GetObjectId (& PyId_stderr );
12911322 if (ferr == NULL || ferr == Py_None ) {
12921323 /* sys.stderr is not set yet or set to None,
12931324 no need to try to display the exception */
1294- goto display_stack ;
1325+ return 0 ;
12951326 }
12961327
12971328 PyErr_NormalizeException (& exception , & v , & tb );
@@ -1302,7 +1333,7 @@ _Py_PrintFatalError(int fd)
13021333 PyException_SetTraceback (v , tb );
13031334 if (exception == NULL ) {
13041335 /* PyErr_NormalizeException() failed */
1305- goto display_stack ;
1336+ return 0 ;
13061337 }
13071338
13081339 has_tb = (tb != Py_None );
@@ -1318,28 +1349,9 @@ _Py_PrintFatalError(int fd)
13181349 else
13191350 Py_DECREF (res );
13201351
1321- if (has_tb )
1322- return ;
1323-
1324- display_stack :
1325- #ifdef WITH_THREAD
1326- /* PyGILState_GetThisThreadState() works even if the GIL was released */
1327- tstate = PyGILState_GetThisThreadState ();
1328- #else
1329- tstate = PyThreadState_GET ();
1330- #endif
1331- if (tstate == NULL ) {
1332- /* _Py_DumpTracebackThreads() requires the thread state to display
1333- * frames */
1334- return ;
1335- }
1336-
1337- fputc ('\n' , stderr );
1338- fflush (stderr );
1339-
1340- /* display the current Python stack */
1341- _Py_DumpTracebackThreads (fd , tstate -> interp , tstate );
1352+ return has_tb ;
13421353}
1354+
13431355/* Print fatal error message and abort */
13441356
13451357void
@@ -1365,10 +1377,14 @@ Py_FatalError(const char *msg)
13651377
13661378 /* Print the exception (if an exception is set) with its traceback,
13671379 * or display the current Python stack. */
1368- _Py_PrintFatalError (fd );
1380+ if (!_Py_FatalError_PrintExc (fd ))
1381+ _Py_FatalError_DumpTracebacks (fd );
13691382
1370- /* Flush sys.stdout and sys.stderr */
1371- flush_std_files ();
1383+ /* Check if the current Python thread hold the GIL */
1384+ if (PyThreadState_GET () != NULL ) {
1385+ /* Flush sys.stdout and sys.stderr */
1386+ flush_std_files ();
1387+ }
13721388
13731389 /* The main purpose of faulthandler is to display the traceback. We already
13741390 * did our best to display it. So faulthandler can now be disabled.
0 commit comments