4

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)
2
  • Why don't you simply do crashHandler(the_arguments)? These things should all be mocked when doing unit-testing. Commented Oct 3, 2013 at 11:46
  • Of course, that's a possibility. But I want to test under more realistic circumstances. Maybe an unhandled C exception leaves the Python interpreter in a brittle state? Those are the things I would like to test. Commented Oct 3, 2013 at 13:40

1 Answer 1

2

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).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.