監控 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 事件。如果 valueStopIteration 的例項,則使用它。否則,將使用 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

BRANCH_LEFT

PY_MONITORING_EVENT_BRANCH_RIGHT

BRANCH_RIGHT

PY_MONITORING_EVENT_CALL

CALL

PY_MONITORING_EVENT_C_RAISE

C_RAISE

PY_MONITORING_EVENT_C_RETURN

C_RETURN

PY_MONITORING_EVENT_EXCEPTION_HANDLED

EXCEPTION_HANDLED

PY_MONITORING_EVENT_INSTRUCTION

INSTRUCTION

PY_MONITORING_EVENT_JUMP

JUMP

PY_MONITORING_EVENT_LINE

LINE

PY_MONITORING_EVENT_PY_RESUME

PY_RESUME

PY_MONITORING_EVENT_PY_RETURN

PY_RETURN

PY_MONITORING_EVENT_PY_START

PY_START

PY_MONITORING_EVENT_PY_THROW

PY_THROW

PY_MONITORING_EVENT_PY_UNWIND

PY_UNWIND

PY_MONITORING_EVENT_PY_YIELD

PY_YIELD

PY_MONITORING_EVENT_RAISE

RAISE

PY_MONITORING_EVENT_RERAISE

RERAISE

PY_MONITORING_EVENT_STOP_ITERATION

STOP_ITERATION

int PyMonitoring_ExitScope(void)

退出上次使用 PyMonitoring_EnterScope() 進入的範圍。

int PY_MONITORING_IS_INSTRUMENTED_EVENT(uint8_t ev)

如果與事件 ID *ev* 對應的事件是本地事件,則返回 true。

在 3.13 版本加入。

從 3.14 版本開始已棄用: 此函式是 軟棄用 的。