Commit 84092ac3 authored by Victor Stinner's avatar Victor Stinner

Issue #23571: Fix reentrant call to Py_FatalError()

Flushing sys.stdout and sys.stderr in Py_FatalError() can call again
Py_FatalError(). Add a reentrant flag to detect this case and just abort at the
second call.
parent b0749ca9
...@@ -2663,6 +2663,19 @@ void ...@@ -2663,6 +2663,19 @@ void
Py_FatalError(const char *msg) Py_FatalError(const char *msg)
{ {
const int fd = fileno(stderr); const int fd = fileno(stderr);
static int reentrant = 0;
#ifdef MS_WINDOWS
size_t len;
WCHAR* buffer;
size_t i;
#endif
if (reentrant) {
/* Py_FatalError() caused a second fatal error.
Example: flush_std_files() raises a recursion error. */
goto exit;
}
reentrant = 1;
fprintf(stderr, "Fatal Python error: %s\n", msg); fprintf(stderr, "Fatal Python error: %s\n", msg);
fflush(stderr); /* it helps in Windows debug build */ fflush(stderr); /* it helps in Windows debug build */
...@@ -2680,25 +2693,23 @@ Py_FatalError(const char *msg) ...@@ -2680,25 +2693,23 @@ Py_FatalError(const char *msg)
_PyFaulthandler_Fini(); _PyFaulthandler_Fini();
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
{ len = strlen(msg);
size_t len = strlen(msg);
WCHAR* buffer; /* Convert the message to wchar_t. This uses a simple one-to-one
size_t i; conversion, assuming that the this error message actually uses ASCII
only. If this ceases to be true, we will have to convert. */
/* Convert the message to wchar_t. This uses a simple one-to-one buffer = alloca( (len+1) * (sizeof *buffer));
conversion, assuming that the this error message actually uses ASCII for( i=0; i<=len; ++i)
only. If this ceases to be true, we will have to convert. */ buffer[i] = msg[i];
buffer = alloca( (len+1) * (sizeof *buffer)); OutputDebugStringW(L"Fatal Python error: ");
for( i=0; i<=len; ++i) OutputDebugStringW(buffer);
buffer[i] = msg[i]; OutputDebugStringW(L"\n");
OutputDebugStringW(L"Fatal Python error: "); #endif /* MS_WINDOWS */
OutputDebugStringW(buffer);
OutputDebugStringW(L"\n"); exit:
} #if defined(MS_WINDOWS) && defined(_DEBUG)
#ifdef _DEBUG
DebugBreak(); DebugBreak();
#endif #endif
#endif /* MS_WINDOWS */
abort(); abort();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment