(Merge 3.4) Issue #23571: Py_FatalError() now tries to flush sys.stdout and
sys.stderr

It should help to see exceptions when stderr if buffered: PyErr_Display() calls
sys.stderr.write(), it doesn't write into stderr file descriptor directly.
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index ef7d25e..d611c7a 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -546,7 +546,7 @@
     _Py_Finalizing = tstate;
     initialized = 0;
 
-    /* Flush stdout+stderr */
+    /* Flush sys.stdout and sys.stderr */
     flush_std_files();
 
     /* Disable signal handling */
@@ -575,7 +575,7 @@
     /* Destroy all modules */
     PyImport_Cleanup();
 
-    /* Flush stdout+stderr (again, in case more was printed) */
+    /* Flush sys.stdout and sys.stderr (again, in case more was printed) */
     flush_std_files();
 
     /* Collect final garbage.  This disposes of cycles created by
@@ -1253,6 +1253,7 @@
 static void
 _Py_PrintFatalError(int fd)
 {
+    PyObject *ferr, *res;
     PyObject *exception, *v, *tb;
     int has_tb;
     PyThreadState *tstate;
@@ -1263,6 +1264,13 @@
         goto display_stack;
     }
 
+    ferr = _PySys_GetObjectId(&PyId_stderr);
+    if (ferr == NULL || ferr == Py_None) {
+        /* sys.stderr is not set yet or set to None,
+           no need to try to display the exception */
+        goto display_stack;
+    }
+
     PyErr_NormalizeException(&exception, &v, &tb);
     if (tb == NULL) {
         tb = Py_None;
@@ -1270,7 +1278,7 @@
     }
     PyException_SetTraceback(v, tb);
     if (exception == NULL) {
-        /* too bad, PyErr_NormalizeException() failed */
+        /* PyErr_NormalizeException() failed */
         goto display_stack;
     }
 
@@ -1279,6 +1287,14 @@
     Py_XDECREF(exception);
     Py_XDECREF(v);
     Py_XDECREF(tb);
+
+    /* sys.stderr may be buffered: call sys.stderr.flush() */
+    res = _PyObject_CallMethodId(ferr, &PyId_flush, "");
+    if (res == NULL)
+        PyErr_Clear();
+    else
+        Py_DECREF(res);
+
     if (has_tb)
         return;
 
@@ -1307,10 +1323,16 @@
     fprintf(stderr, "Fatal Python error: %s\n", msg);
     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. */
     _Py_PrintFatalError(fd);
 
+    /* Flush sys.stdout and sys.stderr */
+    flush_std_files();
+
     /* The main purpose of faulthandler is to display the traceback. We already
-     * did our best to display it. So faulthandler can now be disabled. */
+     * did our best to display it. So faulthandler can now be disabled.
+     * (Don't trigger it on abort().) */
     _PyFaulthandler_Fini();
 
 #ifdef MS_WINDOWS