[Python-checkins] cpython (merge 3.4 -> default): (Merge 3.4) Issue #23571: Fix reentrant call to Py_FatalError()

victor.stinner python-checkins at python.org
Wed Mar 25 01:55:52 CET 2015


https://hg.python.org/cpython/rev/e9ba95418af8
changeset:   95189:e9ba95418af8
parent:      95187:43c2a09a7c7a
parent:      95188:1c2376825dd2
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Wed Mar 25 01:55:14 2015 +0100
summary:
  (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.

files:
  Python/pylifecycle.c |  43 ++++++++++++++++++++-----------
  1 files changed, 27 insertions(+), 16 deletions(-)


diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1319,6 +1319,19 @@
 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 @@
     _PyFaulthandler_Fini();
 
 #ifdef MS_WINDOWS
-    {
-        size_t len = strlen(msg);
-        WCHAR* buffer;
-        size_t i;
+    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");
-    }
-#ifdef _DEBUG
+    /* 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();
 }
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list