Skip to content

Commit 2bafc0d

Browse files
authored
[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).
1 parent b25b725 commit 2bafc0d

3 files changed

Lines changed: 35 additions & 4 deletions

File tree

Lib/test/test_faulthandler.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,34 @@ def test_raise_exception(self):
755755
3,
756756
name)
757757

758+
@unittest.skipUnless(MS_WINDOWS, 'specific to Windows')
759+
def test_raise_nonfatal_exception(self):
760+
# These exceptions are not strictly errors. Letting
761+
# faulthandler display the traceback when they are
762+
# raised is likely to result in noise. However, they
763+
# may still terminate the process if there is no
764+
# handler installed for them (which there typically
765+
# is, e.g. for debug messages).
766+
for exc in (
767+
0x00000000,
768+
0x34567890,
769+
0x40000000,
770+
0x40001000,
771+
0x70000000,
772+
0x7FFFFFFF,
773+
):
774+
output, exitcode = self.get_output(f"""
775+
import faulthandler
776+
faulthandler.enable()
777+
faulthandler._raise_exception(0x{exc:x})
778+
"""
779+
)
780+
self.assertEqual(output, [])
781+
# On Windows older than 7 SP1, the actual exception code has
782+
# bit 29 cleared.
783+
self.assertIn(exitcode,
784+
(exc, exc & ~0x10000000))
785+
758786
@unittest.skipUnless(MS_WINDOWS, 'specific to Windows')
759787
def test_disable_windows_exc_handler(self):
760788
code = dedent("""

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ Core and Builtins
4545
Library
4646
-------
4747

48+
- bpo-30557: faulthandler now correctly filters and displays exception codes
49+
on Windows
50+
4851
- bpo-30378: Fix the problem that logging.handlers.SysLogHandler cannot
4952
handle IPv6 addresses.
5053

Modules/faulthandler.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,8 @@ faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
373373
DWORD code = exc_info->ExceptionRecord->ExceptionCode;
374374
DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
375375

376-
/* only log fatal exceptions */
377-
if (flags & EXCEPTION_NONCONTINUABLE) {
376+
/* bpo-30557: only log fatal exceptions */
377+
if (!(code & 0x80000000)) {
378378
/* call the next exception handler */
379379
return EXCEPTION_CONTINUE_SEARCH;
380380
}
@@ -391,8 +391,8 @@ faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
391391
case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
392392
case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
393393
default:
394-
PUTS(fd, "code ");
395-
_Py_DumpDecimal(fd, code);
394+
PUTS(fd, "code 0x");
395+
_Py_DumpHexadecimal(fd, code, 8);
396396
}
397397
PUTS(fd, "\n\n");
398398

0 commit comments

Comments
 (0)