简体   繁体   English

在Python中引发未处理的C异常

[英]Raise unhandled C exception in Python

I am extending a Python 2.7.5 app for Windows. 我正在为Windows扩展一个Python 2.7.5应用程序。 The app uses SetUnhandledExceptionFilter to install a Python function that is called when an unhandled C exception occurs: 该应用程序使用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)

(I will give the code for PEXCEPTION_POINTERS below because I don't think it's relevant for the purpose of this question.) (我将在下面给出PEXCEPTION_POINTERS的代码,因为我不认为它与此问题的目的相关。)

In its original form, crashHandler does some logging and shuts down the process. 在其原始形式中, crashHandler执行一些日志记录并关闭该过程。 I have observed it deal with unhandled exceptions a few times, so I'm pretty confident that crashHandler is correctly installed as an UnhandledExceptionFilter. 我已经观察到它处理了几次未处理的异常,因此我非常确信crashHandler是作为UnhandledExceptionFilter正确安装的。

I have made some modifications to crashHandler and would now like to test it. 我对crashHandler做了一些修改,现在想测试一下。 To do this, my idea would be to programmatically raise a C exception that should then be handled by crashHandler . 为此,我的想法是以编程方式引发一个C异常,然后由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 . 因此异常会立即被Python解释器捕获,因此不会传播到我的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 ? 我怎样才能a)禁用Python的异常处理或b)以编程方式引发一个未被Python的异常处理机制捕获并传播到我的crashHandler的C异常?


Here's the code for PEXCEPTION_POINTERS : 这是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. windll模块自动捕获调用中发生的Windows SEH异常,并将它们转换为WindowsError python异常。 Hence they are not unhandled exceptions. 因此,它们不是未处理的例外。

You need to use an API which doesn't have such a good wrapper. 您需要使用没有这么好的包装器的API。

Your best bet is to use a C extension module which causes an access violation by dereferencing a random pointer (or null). 最好的办法是使用C扩展模块,通过取消引用随机指针(或null)来导致访问冲突。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM