[3.6] bpo-30557: faulthandler now correctly filters and displays exception … (#1960)
* 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).
diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py
index 01cbae3..20fe1e2 100644
--- a/Lib/test/test_faulthandler.py
+++ b/Lib/test/test_faulthandler.py
@@ -756,6 +756,34 @@
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("""
import faulthandler
diff --git a/Misc/NEWS b/Misc/NEWS
index 1656e07..6177ee4 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -45,6 +45,9 @@
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.
diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c
index 61fc490..2efa998 100644
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -373,8 +373,8 @@
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 @@
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");