diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2015-03-25 00:54:46 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2015-03-25 00:54:46 (GMT) |
commit | 84092ac3705ffe371f5f1ec8ecc8c2830861ba9e (patch) | |
tree | 5f03eacc8c74310a435eb7047488e04998b34d28 /Python | |
parent | b0749ca933a6806cfa81d22718bde69409154654 (diff) | |
download | cpython-84092ac3705ffe371f5f1ec8ecc8c2830861ba9e.zip cpython-84092ac3705ffe371f5f1ec8ecc8c2830861ba9e.tar.gz cpython-84092ac3705ffe371f5f1ec8ecc8c2830861ba9e.tar.bz2 |
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.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/pythonrun.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c index c16ebc4..9b2405f 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -2663,6 +2663,19 @@ void Py_FatalError(const char *msg) { 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); fflush(stderr); /* it helps in Windows debug build */ @@ -2680,25 +2693,23 @@ Py_FatalError(const char *msg) _PyFaulthandler_Fini(); #ifdef MS_WINDOWS - { - size_t len = strlen(msg); - WCHAR* buffer; - size_t i; - - /* Convert the message to wchar_t. This uses a simple one-to-one - conversion, assuming that the this error message actually uses ASCII - only. If this ceases to be true, we will have to convert. */ - buffer = alloca( (len+1) * (sizeof *buffer)); - for( i=0; i<=len; ++i) - buffer[i] = msg[i]; - OutputDebugStringW(L"Fatal Python error: "); - OutputDebugStringW(buffer); - OutputDebugStringW(L"\n"); - } -#ifdef _DEBUG + len = strlen(msg); + + /* Convert the message to wchar_t. This uses a simple one-to-one + conversion, assuming that the this error message actually uses ASCII + only. If this ceases to be true, we will have to convert. */ + buffer = alloca( (len+1) * (sizeof *buffer)); + for( i=0; i<=len; ++i) + buffer[i] = msg[i]; + OutputDebugStringW(L"Fatal Python error: "); + OutputDebugStringW(buffer); + OutputDebugStringW(L"\n"); +#endif /* MS_WINDOWS */ + +exit: +#if defined(MS_WINDOWS) && defined(_DEBUG) DebugBreak(); #endif -#endif /* MS_WINDOWS */ abort(); } |