监控 C API¶
在 3.13 版中添加。
一个扩展可能需要与事件监视系统进行交互。 订阅事件和注册回调都可通过在 sys.monitoring 中暴露的 Python API 来完成。
生成执行事件¶
下面的函数使得扩展可以在模拟执行 Python 代码时触发监控事件。 这样的函数都接受一个 PyMonitoringState 结构体,其中包含有关事件激活状态的简明信息以及事件参数 ,此类参数包括代表代码对象的 PyObject*、指令偏移量,有时还包括额外的、事件专属的参数(请参阅 sys.monitoring 了解有关不同事件回调签名的详情)。 codelike 参数应为 types.CodeType 的实例或是某个模拟它的类型。
VM 会在触发事件时禁用跟踪,因此用户不需要额外的操作。
监控函数被调用时不应设置异常,除非是下面列出的用于处理当前异常的函数。
-
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_FireBranchEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)¶
发出
BRANCH事件。
-
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事件。event with the current ).
-
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实例,它将被使用。 在其他情况下,将新建一个StopIteration实例并以value作为其参数。
管理监控状态¶
监控状态可在监控作用域的协助下进行管理。 一个作用域通常对应一个 python 函数。
-
int PyMonitoring_EnterScope(PyMonitoringState *state_array, uint64_t *version, const uint8_t *event_types, Py_ssize_t length)¶
Enter a monitored scope.
event_typesis an array of the event IDs for events that may be fired from the scope. For example, the ID of aPY_STARTevent is the valuePY_MONITORING_EVENT_PY_START, which is numerically equal to the base-2 logarithm ofsys.monitoring.events.PY_START.state_arrayis an array with a monitoring state entry for each event inevent_types, it is allocated by the user but populated byPyMonitoring_EnterScope()with information about the activation state of the event. The size ofevent_types(and hence also ofstate_array) is given inlength.The
versionargument is a pointer to a value which should be allocated by the user together withstate_arrayand initialized to 0, and then set only byPyMonitoring_EnterScope()itelf. It allows this function to determine whether event states have changed since the previous call, and to return quickly if they have not.The scopes referred to here are lexical scopes: a function, class or method.
PyMonitoring_EnterScope()should be called whenever the lexical scope is entered. Scopes can be reentered, reusing the same state_array and version, in situations like when emulating a recursive Python function. When a code-like's execution is paused, such as when emulating a generator, the scope needs to be exited and re-entered.The macros for event_types are:
Macro
Event
-
PY_MONITORING_EVENT_BRANCH¶
-
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¶
-
int PyMonitoring_ExitScope(void)¶
Exit the last scope that was entered with
PyMonitoring_EnterScope().