Skip to content

Commit 84092ac

Browse files
committed
Issue python#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.
1 parent b0749ca commit 84092ac

1 file changed

Lines changed: 28 additions & 17 deletions

File tree

‎Python/pythonrun.c‎

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,6 +2663,19 @@ void
26632663
Py_FatalError(const char *msg)
26642664
{
26652665
const int fd = fileno(stderr);
2666+
static int reentrant = 0;
2667+
#ifdef MS_WINDOWS
2668+
size_t len;
2669+
WCHAR* buffer;
2670+
size_t i;
2671+
#endif
2672+
2673+
if (reentrant) {
2674+
/* Py_FatalError() caused a second fatal error.
2675+
Example: flush_std_files() raises a recursion error. */
2676+
goto exit;
2677+
}
2678+
reentrant = 1;
26662679

26672680
fprintf(stderr, "Fatal Python error: %s\n", msg);
26682681
fflush(stderr); /* it helps in Windows debug build */
@@ -2680,25 +2693,23 @@ Py_FatalError(const char *msg)
26802693
_PyFaulthandler_Fini();
26812694

26822695
#ifdef MS_WINDOWS
2683-
{
2684-
size_t len = strlen(msg);
2685-
WCHAR* buffer;
2686-
size_t i;
2687-
2688-
/* Convert the message to wchar_t. This uses a simple one-to-one
2689-
conversion, assuming that the this error message actually uses ASCII
2690-
only. If this ceases to be true, we will have to convert. */
2691-
buffer = alloca( (len+1) * (sizeof *buffer));
2692-
for( i=0; i<=len; ++i)
2693-
buffer[i] = msg[i];
2694-
OutputDebugStringW(L"Fatal Python error: ");
2695-
OutputDebugStringW(buffer);
2696-
OutputDebugStringW(L"\n");
2697-
}
2698-
#ifdef _DEBUG
2696+
len = strlen(msg);
2697+
2698+
/* Convert the message to wchar_t. This uses a simple one-to-one
2699+
conversion, assuming that the this error message actually uses ASCII
2700+
only. If this ceases to be true, we will have to convert. */
2701+
buffer = alloca( (len+1) * (sizeof *buffer));
2702+
for( i=0; i<=len; ++i)
2703+
buffer[i] = msg[i];
2704+
OutputDebugStringW(L"Fatal Python error: ");
2705+
OutputDebugStringW(buffer);
2706+
OutputDebugStringW(L"\n");
2707+
#endif /* MS_WINDOWS */
2708+
2709+
exit:
2710+
#if defined(MS_WINDOWS) && defined(_DEBUG)
26992711
DebugBreak();
27002712
#endif
2701-
#endif /* MS_WINDOWS */
27022713
abort();
27032714
}
27042715

0 commit comments

Comments
 (0)