diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2015-03-25 00:55:14 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2015-03-25 00:55:14 (GMT) |
commit | 53345a40bcbf6d71705533b658b2940dad31a684 (patch) | |
tree | 7826b29396823e696376358c7f109aa00b8a191e | |
parent | 09ce2786e4a7a9ea2be32856f4db327f0b72d6cd (diff) | |
parent | 84092ac3705ffe371f5f1ec8ecc8c2830861ba9e (diff) | |
download | cpython-53345a40bcbf6d71705533b658b2940dad31a684.zip cpython-53345a40bcbf6d71705533b658b2940dad31a684.tar.gz cpython-53345a40bcbf6d71705533b658b2940dad31a684.tar.bz2 |
(Merge 3.4) 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.
-rw-r--r-- | Python/pylifecycle.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index d611c7a..38543e0 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1319,6 +1319,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 */ @@ -1336,25 +1349,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(); } |