]> granicus.if.org Git - python/commitdiff
[3.6] bpo-30557: faulthandler now correctly filters and displays exception … (#1960)
authorSteve Dower <steve.dower@microsoft.com>
Tue, 6 Jun 2017 20:47:14 +0000 (13:47 -0700)
committerGitHub <noreply@github.com>
Tue, 6 Jun 2017 20:47:14 +0000 (13:47 -0700)
* bpo-30557: faulthandler now correctly filters and displays exception codes on Windows (#1924)

* bpo-30557: faulthandler now correctly filters and displays exception codes on Windows

* Adds test for non-fatal exceptions.

* Adds bpo number to comment.

* bpo-30557: Fix test_faulthandler (#1969)

On Windows 8, 8.1 and 10 at least, the exit code is the exception
code (no bit is cleared).

Lib/test/test_faulthandler.py
Misc/NEWS
Modules/faulthandler.c

index 01cbae3f200b1aa26586b6ea62bc2ef6ace5ac84..20fe1e2655946f5bc7a18f2940a50057bb6014d6 100644 (file)
@@ -755,6 +755,34 @@ class FaultHandlerTests(unittest.TestCase):
                 3,
                 name)
 
+    @unittest.skipUnless(MS_WINDOWS, 'specific to Windows')
+    def test_raise_nonfatal_exception(self):
+        # These exceptions are not strictly errors. Letting
+        # faulthandler display the traceback when they are
+        # raised is likely to result in noise. However, they
+        # may still terminate the process if there is no
+        # handler installed for them (which there typically
+        # is, e.g. for debug messages).
+        for exc in (
+            0x00000000,
+            0x34567890,
+            0x40000000,
+            0x40001000,
+            0x70000000,
+            0x7FFFFFFF,
+        ):
+            output, exitcode = self.get_output(f"""
+                import faulthandler
+                faulthandler.enable()
+                faulthandler._raise_exception(0x{exc:x})
+                """
+            )
+            self.assertEqual(output, [])
+            # On Windows older than 7 SP1, the actual exception code has
+            # bit 29 cleared.
+            self.assertIn(exitcode,
+                          (exc, exc & ~0x10000000))
+
     @unittest.skipUnless(MS_WINDOWS, 'specific to Windows')
     def test_disable_windows_exc_handler(self):
         code = dedent("""
index 1656e07f6eb1df27d04af7878e1861f65b327795..6177ee40ab657737a0c18433220c1a5bfd4b400a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -45,6 +45,9 @@ Core and Builtins
 Library
 -------
 
+- bpo-30557: faulthandler now correctly filters and displays exception codes
+  on Windows
+
 - bpo-30378: Fix the problem that logging.handlers.SysLogHandler cannot
   handle IPv6 addresses.
 
index 61fc4908b0fe9bf9144de6cc8eb24f1ee6a8847f..2efa998ff89aac1a06946c0d1ddb9266356d9bd6 100644 (file)
@@ -373,8 +373,8 @@ faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
     DWORD code = exc_info->ExceptionRecord->ExceptionCode;
     DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
 
-    /* only log fatal exceptions */
-    if (flags & EXCEPTION_NONCONTINUABLE) {
+    /* bpo-30557: only log fatal exceptions */
+    if (!(code & 0x80000000)) {
         /* call the next exception handler */
         return EXCEPTION_CONTINUE_SEARCH;
     }
@@ -391,8 +391,8 @@ faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
     case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
     case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
     default:
-        PUTS(fd, "code ");
-        _Py_DumpDecimal(fd, code);
+        PUTS(fd, "code 0x");
+        _Py_DumpHexadecimal(fd, code, 8);
     }
     PUTS(fd, "\n\n");