diff options
-rw-r--r-- | Lib/test/test_faulthandler.py | 16 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2017-10-09-17-42-30.bpo-31701.NRrVel.rst | 1 | ||||
-rw-r--r-- | Modules/faulthandler.c | 22 |
3 files changed, 36 insertions, 3 deletions
diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index 889e641..e0e53c2 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -749,6 +749,22 @@ class FaultHandlerTests(unittest.TestCase): name) @unittest.skipUnless(MS_WINDOWS, 'specific to Windows') + def test_ignore_exception(self): + for exc_code in ( + 0xE06D7363, # MSC exception ("Emsc") + 0xE0434352, # COM Callable Runtime exception ("ECCR") + ): + code = f""" + import faulthandler + faulthandler.enable() + faulthandler._raise_exception({exc_code}) + """ + code = dedent(code) + output, exitcode = self.get_output(code) + self.assertEqual(output, []) + self.assertEqual(exitcode, exc_code) + + @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 diff --git a/Misc/NEWS.d/next/Library/2017-10-09-17-42-30.bpo-31701.NRrVel.rst b/Misc/NEWS.d/next/Library/2017-10-09-17-42-30.bpo-31701.NRrVel.rst new file mode 100644 index 0000000..129b74e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-09-17-42-30.bpo-31701.NRrVel.rst @@ -0,0 +1 @@ +On Windows, faulthandler.enable() now ignores MSC and COM exceptions. diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index c2c2c53..dba646b 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -360,6 +360,23 @@ faulthandler_fatal_error(int signum) } #ifdef MS_WINDOWS +static int +faulthandler_ignore_exception(DWORD code) +{ + /* bpo-30557: ignore exceptions which are not errors */ + if (!(code & 0x80000000)) { + return 1; + } + /* bpo-31701: ignore MSC and COM exceptions + E0000000 + code */ + if (code == 0xE06D7363 /* MSC exception ("Emsc") */ + || code == 0xE0434352 /* COM Callable Runtime exception ("ECCR") */) { + return 1; + } + /* Interesting exception: log it with the Python traceback */ + return 0; +} + static LONG WINAPI faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info) { @@ -367,9 +384,8 @@ faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info) DWORD code = exc_info->ExceptionRecord->ExceptionCode; DWORD flags = exc_info->ExceptionRecord->ExceptionFlags; - /* bpo-30557: only log fatal exceptions */ - if (!(code & 0x80000000)) { - /* call the next exception handler */ + if (faulthandler_ignore_exception(code)) { + /* ignore the exception: call the next exception handler */ return EXCEPTION_CONTINUE_SEARCH; } |