監控 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_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
事件。
-
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)¶
進入一個受監控的範圍。
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¶
-
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)¶
退出使用
PyMonitoring_EnterScope()
進入的最後一個作用域。