Issue40946
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2020-06-11 06:08 by eryksun, last changed 2022-04-11 14:59 by admin.
Messages (1) | |||
---|---|---|---|
msg371257 - (view) | Author: Eryk Sun (eryksun) * | Date: 2020-06-11 06:08 | |
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' |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:59:32 | admin | set | github: 85118 |
2020-06-11 06:09:16 | eryksun | set | keywords: + easy |
2020-06-11 06:08:46 | eryksun | create |