3

Windows 用の Python 2.7.5 アプリを拡張しています。アプリはSetUnhandledExceptionFilter、未処理の C 例外が発生したときに呼び出される 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 インタープリターによってキャッチされるため、 my に伝播されませんcrashHandler

a) Python の例外処理を無効にするか、b) Python の例外処理メカニズムによってキャッチされず、my.xml に伝播される 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)
4

1 に答える 1

2

windll モジュールは、呼び出しで発生する Windows SEH 例外を自動的にキャッチし、それらを WindowsError Python 例外に変換します。したがって、それらは未処理の例外ではありません。

そのような優れたラッパーを持たない API を使用する必要があります。

最善の策は、ランダム ポインター (または null) を逆参照することによってアクセス違反を引き起こす C 拡張モジュールを使用することです。

于 2013-10-03T09:42:18.697 に答える