summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_faulthandler.py26
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/faulthandler.c8
3 files changed, 33 insertions, 4 deletions
diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py
index 626e245..c965d67 100644
--- a/Lib/test/test_faulthandler.py
+++ b/Lib/test/test_faulthandler.py
@@ -755,6 +755,32 @@ class FaultHandlerTests(unittest.TestCase):
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, [])
+ # Actual exception code has bit 4 cleared
+ self.assertEqual(exitcode, 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 e6e8f95..1b5794b 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -345,6 +345,9 @@ Extension Modules
Library
-------
+- bpo-30557: faulthandler now correctly filters and displays exception codes
+ on Windows
+
- bpo-30526: Add TextIOWrapper.reconfigure() and a TextIOWrapper.write_through
attribute.
diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c
index dcfebf2..39b70bc 100644
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -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");