Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e0deff3

Browse files
committed
(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.
2 parents 454bd3a + ec4f959 commit e0deff3

1 file changed

Lines changed: 26 additions & 4 deletions

File tree

Python/pylifecycle.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
12531253
static 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

Comments
 (0)