监控 C API¶
在 3.13 版本加入。
扩展可能需要与事件监控系统交互。可以通过 sys.monitoring
中公开的 Python API 订阅事件和注册回调。
生成执行事件¶
以下函数使扩展能够在模拟 Python 代码执行时触发监控事件。每个函数都接受一个 PyMonitoringState
结构,该结构包含事件激活状态的简洁信息,以及事件参数,其中包括表示代码对象的 PyObject*
、指令偏移量以及有时额外的、特定于事件的参数(有关不同事件回调签名的详细信息,请参阅 sys.monitoring
)。codelike
参数应该是 types.CodeType
的实例或模拟它的类型。
虚拟机在触发事件时禁用跟踪,因此用户代码无需执行此操作。
监控函数不应在设置异常的情况下调用,除非下面列出的那些与当前异常一起工作的函数。
-
type PyMonitoringState¶
表示事件类型的状态。它由用户分配,其内容由下面描述的监控 API 函数维护。
所有以下函数在成功时返回 0,在出错时返回 -1(并设置异常)。
有关事件的描述,请参阅 sys.monitoring
。
-
int PyMonitoring_FirePyStartEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
触发
PY_START
事件。
-
int PyMonitoring_FirePyResumeEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
触发
PY_RESUME
事件。
-
int PyMonitoring_FirePyReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *retval)¶
触发
PY_RETURN
事件。
-
int PyMonitoring_FirePyYieldEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *retval)¶
触发
PY_YIELD
事件。
-
int PyMonitoring_FireCallEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *callable, PyObject *arg0)¶
触发
CALL
事件。
-
int PyMonitoring_FireLineEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, int lineno)¶
触发
LINE
事件。
-
int PyMonitoring_FireJumpEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)¶
触发
JUMP
事件。
-
int PyMonitoring_FireBranchLeftEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)¶
触发
BRANCH_LEFT
事件。
-
int PyMonitoring_FireBranchRightEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)¶
触发
BRANCH_RIGHT
事件。
-
int PyMonitoring_FireCReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *retval)¶
触发
C_RETURN
事件。
-
int PyMonitoring_FirePyThrowEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
使用当前异常(由
PyErr_GetRaisedException()
返回)触发PY_THROW
事件。
-
int PyMonitoring_FireRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
使用当前异常(由
PyErr_GetRaisedException()
返回)触发RAISE
事件。
-
int PyMonitoring_FireCRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
使用当前异常(由
PyErr_GetRaisedException()
返回)触发C_RAISE
事件。
-
int PyMonitoring_FireReraiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
使用当前异常(由
PyErr_GetRaisedException()
返回)触发RERAISE
事件。
-
int PyMonitoring_FireExceptionHandledEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
使用当前异常(由
PyErr_GetRaisedException()
返回)触发EXCEPTION_HANDLED
事件。
-
int PyMonitoring_FirePyUnwindEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
使用当前异常(由
PyErr_GetRaisedException()
返回)触发PY_UNWIND
事件。
-
int PyMonitoring_FireStopIterationEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *value)¶
触发
STOP_ITERATION
事件。如果value
是StopIteration
的实例,则使用它。否则,将使用value
作为其参数创建一个新的StopIteration
实例。
管理监控状态¶
监控状态可以通过监控范围来管理。一个范围通常对应一个 Python 函数。
-
int PyMonitoring_EnterScope(PyMonitoringState *state_array, uint64_t *version, const uint8_t *event_types, Py_ssize_t length)¶
进入一个受监控的范围。
event_types
是可能从该范围触发的事件的事件 ID 数组。例如,PY_START
事件的 ID 是值PY_MONITORING_EVENT_PY_START
,其数值等于sys.monitoring.events.PY_START
的以 2 为底的对数。state_array
是一个数组,其中包含event_types
中每个事件的监控状态条目,它由用户分配,但由PyMonitoring_EnterScope()
填充,其中包含有关事件激活状态的信息。event_types
(以及state_array
)的大小由length
给出。version
参数是指向一个值的指针,该值应由用户与state_array
一起分配并初始化为 0,然后仅由PyMonitoring_EnterScope()
本身设置。它允许此函数确定自上次调用以来事件状态是否已更改,如果未更改则快速返回。此处指的范围是词法范围:一个函数、类或方法。每当进入词法范围时,都应调用
PyMonitoring_EnterScope()
。在模拟递归 Python 函数等情况下,可以重新进入范围,重复使用相同的 *state_array* 和 *version*。当类似代码的执行暂停时,例如在模拟生成器时,需要退出并重新进入范围。用于 *event_types* 的宏是
宏
事件
-
PY_MONITORING_EVENT_BRANCH_LEFT¶
-
PY_MONITORING_EVENT_BRANCH_RIGHT¶
-
PY_MONITORING_EVENT_CALL¶
-
PY_MONITORING_EVENT_C_RAISE¶
-
PY_MONITORING_EVENT_C_RETURN¶
-
PY_MONITORING_EVENT_EXCEPTION_HANDLED¶
-
PY_MONITORING_EVENT_INSTRUCTION¶
-
PY_MONITORING_EVENT_JUMP¶
-
PY_MONITORING_EVENT_LINE¶
-
PY_MONITORING_EVENT_PY_RESUME¶
-
PY_MONITORING_EVENT_PY_RETURN¶
-
PY_MONITORING_EVENT_PY_START¶
-
PY_MONITORING_EVENT_PY_THROW¶
-
PY_MONITORING_EVENT_PY_UNWIND¶
-
PY_MONITORING_EVENT_PY_YIELD¶
-
PY_MONITORING_EVENT_RAISE¶
-
PY_MONITORING_EVENT_RERAISE¶
-
PY_MONITORING_EVENT_STOP_ITERATION¶
-
PY_MONITORING_EVENT_BRANCH_LEFT¶
-
int PyMonitoring_ExitScope(void)¶
退出上次使用
PyMonitoring_EnterScope()
进入的范围。