2013-10-03 4 views
3

Я расширяю приложение Python 2.7.5 для Windows. Приложение использует SetUnhandledExceptionFilter установить функцию Python, которая вызывается, когда возникает необработанное исключение C:Raise unhandled C exception в Python

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

Как я могу либо отключить обработку исключений Python, либо b) программно поднять исключение C, которое не поймано механизмом обработки исключений Python и распространяется на мой 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) 
+0

Почему вы просто не делаете 'crashHandler (the_arguments)'? Все это должно быть обмануто при проведении модульного тестирования. – Bakuriu

+0

Конечно, это возможность. Но я хочу протестировать более реалистичные обстоятельства. Может быть, необработанное исключение C оставляет интерпретатор Python в хрупком состоянии? Это те вещи, которые я хотел бы проверить. –

ответ

2

Модуль windll автоматически перехватывает исключения окна SEH, которые происходят в вызовах, и преобразует их в исключения питона WindowsError. Следовательно, они не являются необработанными исключениями.

Вам необходимо использовать API, который не имеет такой хорошей оболочки.

Лучше всего использовать модуль расширения C, который вызывает нарушение доступа путем разыменования случайного указателя (или null).