I am extending a Python 2.7.5 app for Windows. The app uses SetUnhandledExceptionFilter to install a Python function that is called when an unhandled C exception occurs:
@ctypes.WINFUNCTYPE(ctypes.wintypes.LONG, PEXCEPTION_POINTERS)
def crashHandler(exceptionInfo):
# Some code that deals with the unhandled C exception...
...
windll.kernel32.SetUnhandledExceptionFilter(crashHandler)
(I will give the code for PEXCEPTION_POINTERS below because I don't think it's relevant for the purpose of this question.)
In its original form, crashHandler does some logging and shuts down the process. I have observed it deal with unhandled exceptions a few times, so I'm pretty confident that crashHandler is correctly installed as an UnhandledExceptionFilter.
I have made some modifications to crashHandler and would now like to test it. To do this, my idea would be to programmatically raise a C exception that should then be handled by crashHandler. I tried the following:
>>> 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
So the exception is immediately caught by the Python interpreter, hence does not get propagated to my crashHandler.
How can I either a) disable Python's exception handling or b) programmatically raise a C exception that is not caught by Python's exception handling mechanism and gets propagated to my crashHandler?
Here's the code for 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)
The windll module automatically catches windows SEH exceptions which occur in calls, and converts them to WindowsError python exceptions. Hence they are not unhandled exceptions.
You need to use an API which doesn't have such a good wrapper.
Your best bet is to use a C extension module which causes an access violation by dereferencing a random pointer (or null).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With