Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Windows] SuppressCrashReport should set SEM_FAILCRITICALERRORS #85118

Open
eryksun opened this issue Jun 11, 2020 · 2 comments
Open

[Windows] SuppressCrashReport should set SEM_FAILCRITICALERRORS #85118

eryksun opened this issue Jun 11, 2020 · 2 comments
Labels
3.10 only security fixes easy tests Tests in the Lib/test dir type-feature A feature request or enhancement

Comments

@eryksun
Copy link
Contributor

eryksun commented Jun 11, 2020

BPO 40946
Nosy @eryksun

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2020-06-11.06:08:46.074>
labels = ['easy', 'type-feature', '3.10']
title = 'SuppressCrashReport should set SEM_FAILCRITICALERRORS in Windows'
updated_at = <Date 2020-06-11.06:09:16.842>
user = 'https://github.com/eryksun'

bugs.python.org fields:

activity = <Date 2020-06-11.06:09:16.842>
actor = 'eryksun'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = []
creation = <Date 2020-06-11.06:08:46.074>
creator = 'eryksun'
dependencies = []
files = []
hgrepos = []
issue_num = 40946
keywords = ['easy']
message_count = 1.0
messages = ['371257']
nosy_count = 1.0
nosy_names = ['eryksun']
pr_nums = []
priority = 'normal'
resolution = None
stage = 'needs patch'
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue40946'
versions = ['Python 3.10']

Linked PRs

@eryksun
Copy link
Contributor Author

eryksun commented Jun 11, 2020

In test.support, suppress_msvcrt_asserts sets the process error mode to include SEM_FAILCRITICALERRORS, SEM_NOGPFAULTERRORBOX, SEM_NOALIGNMENTFAULTEXCEPT, and SEM_NOOPENFILEERRORBOX. In contrast, the SuppressCrashReport context manager in the same module only sets SEM_NOGPFAULTERRORBOX. It should also set SEM_FAILCRITICALERRORS (i.e. do not display the critical-error-handler message box).

Including SEM_NOOPENFILEERRORBOX wouldn't hurt, but it's not of much value since it only affects the deprecated OpenFile function. SEM_NOALIGNMENTFAULTEXCEPT may not be appropriate in a context manager, since it's a one-time setting that can't be reverted, plus x86 and x64 processors aren't even configured by default to generate alignment exceptions; they do fixups in hardware.

---
Discussion

SEM_FAILCRITICALERRORS suppresses normal "hard error" reports sent by the NtRaiseHardError system call -- or by ExRaiseHardError or IoRaiseHardError in the kernel. If reporting a hard error isn't prevented by the error mode, the report gets sent to the ExceptionPort of the process. Normally this is the session's API port (e.g. "\Sessions\1\Windows\ApiPort"). A thread in the session server process (csrss.exe) handles requests sent to this port. In the case of a hard error, ultimately it creates a message box via user32!MessageBoxTimeoutW.

For example:

    NtRaiseHardError = ctypes.windll.ntdll.NtRaiseHardError
    response = (ctypes.c_ulong * 1)()

With the default process error mode, the following raises a hard error dialog for STATUS_UNSUCCESSFUL (0xC0000001), with abort/retry/ignore options:

    >>> NtRaiseHardError(0xC000_0001, 0, 0, None, 0, response)
    0
    >>> response[0]
    2

The normal response value for the above call is limited to abort (2), retry (7), and ignore (4). The response is 0 if the process is set to fail critical errors:

    >>> msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS)
    0
    >>> NtRaiseHardError(0xC000_0001, 0, 0, None, 0, response)
    0
    >>> response[0]
    0

SEM_FAILCRITICALERRORS doesn't suppress all hard-error reporting. The system also checks for an override flag (0x1000_0000) in the status code. This flag is used in many cases, such as WinAPI FatalAppExitW. For example, the following will report a hard error regardless of the process error mode:

    >>> NtRaiseHardError(0xC000_0001 | 0x1000_0000, 0, 0, None, 0, response)
    0
    >>> response[0]
    2

A common case that doesn't use the override flag is when the loader fails to initialize a process.

For the release build of Python 3.10, for example, if "python310.dll" can't be found, the loader tries to raise a hard error with the status code STATUS_DLL_NOT_FOUND (0xC0000135). If the process error mode allows this, the NtRaiseHardError system call won't return until the user clicks on the "OK" button.

    >>> os.rename('amd64/python310.dll', 'amd64/python310.dll.bak')
    >>> # the following returns after clicking OK
    >>> hex(subprocess.call('python'))
    '0xc0000135'

With SEM_FAILCRITICALERRORS set, which by default gets inherited by a child process, sending the hard error report is suppressed (i.e. NtRaiseHardError returns immediately with a response of 0), and the failed child process terminates immediately with the status code STATUS_DLL_NOT_FOUND.

    >>> msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS)
    0
    >>> # the following returns immediately
    >>> hex(subprocess.call('python'))
    '0xc0000135'
@eryksun eryksun added 3.10 only security fixes type-feature A feature request or enhancement easy labels Jun 11, 2020
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@eryksun eryksun added the tests Tests in the Lib/test dir label Aug 8, 2022
@eryksun eryksun changed the title SuppressCrashReport should set SEM_FAILCRITICALERRORS in Windows Aug 8, 2022
@vaishnavi192
Copy link
Contributor

is this issue open?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.10 only security fixes easy tests Tests in the Lib/test dir type-feature A feature request or enhancement
2 participants