@@ -546,7 +546,7 @@ Py_Finalize(void)
546546 _Py_Finalizing = tstate ;
547547 initialized = 0 ;
548548
549- /* Flush stdout+ stderr */
549+ /* Flush sys. stdout and sys. stderr */
550550 flush_std_files ();
551551
552552 /* Disable signal handling */
@@ -575,7 +575,7 @@ Py_Finalize(void)
575575 /* Destroy all modules */
576576 PyImport_Cleanup ();
577577
578- /* Flush stdout+ stderr (again, in case more was printed) */
578+ /* Flush sys. stdout and sys. stderr (again, in case more was printed) */
579579 flush_std_files ();
580580
581581 /* Collect final garbage. This disposes of cycles created by
@@ -1253,6 +1253,7 @@ initstdio(void)
12531253static void
12541254_Py_PrintFatalError (int fd )
12551255{
1256+ PyObject * ferr , * res ;
12561257 PyObject * exception , * v , * tb ;
12571258 int has_tb ;
12581259 PyThreadState * tstate ;
@@ -1263,14 +1264,21 @@ _Py_PrintFatalError(int fd)
12631264 goto display_stack ;
12641265 }
12651266
1267+ ferr = _PySys_GetObjectId (& PyId_stderr );
1268+ if (ferr == NULL || ferr == Py_None ) {
1269+ /* sys.stderr is not set yet or set to None,
1270+ no need to try to display the exception */
1271+ goto display_stack ;
1272+ }
1273+
12661274 PyErr_NormalizeException (& exception , & v , & tb );
12671275 if (tb == NULL ) {
12681276 tb = Py_None ;
12691277 Py_INCREF (tb );
12701278 }
12711279 PyException_SetTraceback (v , tb );
12721280 if (exception == NULL ) {
1273- /* too bad, PyErr_NormalizeException() failed */
1281+ /* PyErr_NormalizeException() failed */
12741282 goto display_stack ;
12751283 }
12761284
@@ -1279,6 +1287,14 @@ _Py_PrintFatalError(int fd)
12791287 Py_XDECREF (exception );
12801288 Py_XDECREF (v );
12811289 Py_XDECREF (tb );
1290+
1291+ /* sys.stderr may be buffered: call sys.stderr.flush() */
1292+ res = _PyObject_CallMethodId (ferr , & PyId_flush , "" );
1293+ if (res == NULL )
1294+ PyErr_Clear ();
1295+ else
1296+ Py_DECREF (res );
1297+
12821298 if (has_tb )
12831299 return ;
12841300
@@ -1307,10 +1323,16 @@ Py_FatalError(const char *msg)
13071323 fprintf (stderr , "Fatal Python error: %s\n" , msg );
13081324 fflush (stderr ); /* it helps in Windows debug build */
13091325
1326+ /* Print the exception (if an exception is set) with its traceback,
1327+ * or display the current Python stack. */
13101328 _Py_PrintFatalError (fd );
13111329
1330+ /* Flush sys.stdout and sys.stderr */
1331+ flush_std_files ();
1332+
13121333 /* The main purpose of faulthandler is to display the traceback. We already
1313- * did our best to display it. So faulthandler can now be disabled. */
1334+ * did our best to display it. So faulthandler can now be disabled.
1335+ * (Don't trigger it on abort().) */
13141336 _PyFaulthandler_Fini ();
13151337
13161338#ifdef MS_WINDOWS
0 commit comments