@@ -1241,31 +1241,62 @@ initstdio(void)
12411241}
12421242
12431243
1244+ static void
1245+ _Py_FatalError_DumpTracebacks (int fd )
1246+ {
1247+ PyThreadState * tstate ;
1248+
1249+ #ifdef WITH_THREAD
1250+ /* PyGILState_GetThisThreadState() works even if the GIL was released */
1251+ tstate = PyGILState_GetThisThreadState ();
1252+ #else
1253+ tstate = PyThreadState_GET ();
1254+ #endif
1255+ if (tstate == NULL ) {
1256+ /* _Py_DumpTracebackThreads() requires the thread state to display
1257+ * frames */
1258+ return ;
1259+ }
1260+
1261+ fputc ('\n' , stderr );
1262+ fflush (stderr );
1263+
1264+ /* display the current Python stack */
1265+ _Py_DumpTracebackThreads (fd , tstate -> interp , tstate );
1266+ }
1267+
12441268/* Print the current exception (if an exception is set) with its traceback,
1245- * or display the current Python stack.
1246- *
1247- * Don't call PyErr_PrintEx() and the except hook, because Py_FatalError() is
1248- * called on catastrophic cases. */
1269+ or display the current Python stack.
12491270
1250- static void
1251- _Py_PrintFatalError (int fd )
1271+ Don't call PyErr_PrintEx() and the except hook, because Py_FatalError() is
1272+ called on catastrophic cases.
1273+
1274+ Return 1 if the traceback was displayed, 0 otherwise. */
1275+
1276+ static int
1277+ _Py_FatalError_PrintExc (int fd )
12521278{
12531279 PyObject * ferr , * res ;
12541280 PyObject * exception , * v , * tb ;
12551281 int has_tb ;
1256- PyThreadState * tstate ;
1282+
1283+ if (PyThreadState_GET () == NULL ) {
1284+ /* The GIL is released: trying to acquire it is likely to deadlock,
1285+ just give up. */
1286+ return 0 ;
1287+ }
12571288
12581289 PyErr_Fetch (& exception , & v , & tb );
12591290 if (exception == NULL ) {
12601291 /* No current exception */
1261- goto display_stack ;
1292+ return 0 ;
12621293 }
12631294
12641295 ferr = _PySys_GetObjectId (& PyId_stderr );
12651296 if (ferr == NULL || ferr == Py_None ) {
12661297 /* sys.stderr is not set yet or set to None,
12671298 no need to try to display the exception */
1268- goto display_stack ;
1299+ return 0 ;
12691300 }
12701301
12711302 PyErr_NormalizeException (& exception , & v , & tb );
@@ -1276,7 +1307,7 @@ _Py_PrintFatalError(int fd)
12761307 PyException_SetTraceback (v , tb );
12771308 if (exception == NULL ) {
12781309 /* PyErr_NormalizeException() failed */
1279- goto display_stack ;
1310+ return 0 ;
12801311 }
12811312
12821313 has_tb = (tb != Py_None );
@@ -1292,28 +1323,9 @@ _Py_PrintFatalError(int fd)
12921323 else
12931324 Py_DECREF (res );
12941325
1295- if (has_tb )
1296- return ;
1297-
1298- display_stack :
1299- #ifdef WITH_THREAD
1300- /* PyGILState_GetThisThreadState() works even if the GIL was released */
1301- tstate = PyGILState_GetThisThreadState ();
1302- #else
1303- tstate = PyThreadState_GET ();
1304- #endif
1305- if (tstate == NULL ) {
1306- /* _Py_DumpTracebackThreads() requires the thread state to display
1307- * frames */
1308- return ;
1309- }
1310-
1311- fputc ('\n' , stderr );
1312- fflush (stderr );
1313-
1314- /* display the current Python stack */
1315- _Py_DumpTracebackThreads (fd , tstate -> interp , tstate );
1326+ return has_tb ;
13161327}
1328+
13171329/* Print fatal error message and abort */
13181330
13191331void
@@ -1339,10 +1351,14 @@ Py_FatalError(const char *msg)
13391351
13401352 /* Print the exception (if an exception is set) with its traceback,
13411353 * or display the current Python stack. */
1342- _Py_PrintFatalError (fd );
1354+ if (!_Py_FatalError_PrintExc (fd ))
1355+ _Py_FatalError_DumpTracebacks (fd );
13431356
1344- /* Flush sys.stdout and sys.stderr */
1345- flush_std_files ();
1357+ /* Check if the current Python thread hold the GIL */
1358+ if (PyThreadState_GET () != NULL ) {
1359+ /* Flush sys.stdout and sys.stderr */
1360+ flush_std_files ();
1361+ }
13461362
13471363 /* The main purpose of faulthandler is to display the traceback. We already
13481364 * did our best to display it. So faulthandler can now be disabled.
0 commit comments