我正在为 Windows 扩展一个 Python 2.7.5 应用程序。该应用程序用于SetUnhandledExceptionFilter
安装一个 Python 函数,当发生未处理的 C 异常时调用该函数:
@ctypes.WINFUNCTYPE(ctypes.wintypes.LONG, PEXCEPTION_POINTERS)
def crashHandler(exceptionInfo):
# Some code that deals with the unhandled C exception...
...
windll.kernel32.SetUnhandledExceptionFilter(crashHandler)
(我将给出PEXCEPTION_POINTERS
下面的代码,因为我认为它与这个问题的目的无关。)
在其原始形式crashHandler
中,进行一些日志记录并关闭进程。我已经观察到它处理了几次未处理的异常,所以我非常有信心将crashHandler
它正确安装为 UnhandledExceptionFilter。
我已经对其进行了一些修改,crashHandler
现在想对其进行测试。为此,我的想法是以编程方式引发一个 C 异常,然后应该由crashHandler
. 我尝试了以下方法:
>>> windll.kernel32.RaiseException(5, 0, 0, None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
WindowsError: [Error 5] Access is denied
>>> windll.kernel32.RaiseException(6, 0, 0, None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
WindowsError: [Error 6] The handle is invalid
因此异常会立即被 Python 解释器捕获,因此不会传播到我的crashHandler
.
我如何 a) 禁用 Python 的异常处理或 b) 以编程方式引发 Python 的异常处理机制未捕获并传播到我的 C 异常crashHandler
?
这是代码PEXCEPTION_POINTERS
:
from ctypes import Structure
import ctypes
EXCEPTION_MAXIMUM_PARAMETERS = 15
class EXCEPTION_RECORD(Structure):
pass
PEXCEPTION_RECORD = ctypes.wintypes.POINTER(EXCEPTION_RECORD)
EXCEPTION_RECORD._fields_ = [
('ExceptionCode', ctypes.wintypes.DWORD),
('ExceptionFlags', ctypes.wintypes.DWORD),
('ExceptionRecord', PEXCEPTION_RECORD),
('ExceptionAddress', ctypes.wintypes.LPVOID),
('NumberParameters', ctypes.wintypes.DWORD),
('ExceptionInformation', ctypes.wintypes.LPVOID * EXCEPTION_MAXIMUM_PARAMETERS),
]
class EXCEPTION_POINTERS(Structure):
_fields_ = [('ExceptionRecord', PEXCEPTION_RECORD),
('ContextRecord', ctypes.wintypes.LPVOID)]
PEXCEPTION_POINTERS = ctypes.wintypes.POINTER(EXCEPTION_POINTERS)