From 6e3d6b5dc22cd06d8c4d44a38a8a3415e4bebb16 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 9 Oct 2017 09:52:32 -0700 Subject: [PATCH] bpo-31701: faulthandler: ignore MSC and COM Windows exception (#3929) bpo-31701: On Windows, faulthandler.enable() now ignores MSC and COM exceptions. --- Lib/test/test_faulthandler.py | 16 ++++++++++++++ .../2017-10-09-17-42-30.bpo-31701.NRrVel.rst | 1 + Modules/faulthandler.c | 22 ++++++++++++++++--- 3 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2017-10-09-17-42-30.bpo-31701.NRrVel.rst diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index 889e6414e39..e0e53c2f829 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -748,6 +748,22 @@ class FaultHandlerTests(unittest.TestCase): 3, 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 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 00000000000..129b74e5ce2 --- /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 c2c2c537b12..dba646b1287 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; }