監控 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()
進入的範圍。