Monitoring C API¶
Added in version 3.13.
An extension may need to interact with the event monitoring system. Subscribingto events and registering callbacks can be done via the Python API exposed insys.monitoring.
Generating Execution Events¶
The functions below make it possible for an extension to fire monitoringevents as it emulates the execution of Python code. Each of these functionsaccepts aPyMonitoringState struct which contains concise informationabout the activation state of events, as well as the event arguments, whichinclude aPyObject* representing the code object, the instruction offsetand sometimes additional, event-specific arguments (seesys.monitoringfor details about the signatures of the different event callbacks).Thecodelike argument should be an instance oftypes.CodeTypeor of a type that emulates it.
The VM disables tracing when firing an event, so there is no need for usercode to do that.
Monitoring functions should not be called with an exception set,except those listed below as working with the current exception.
- typePyMonitoringState¶
Representation of the state of an event type. It is allocated by the userwhile its contents are maintained by the monitoring API functions described below.
All of the functions below return 0 on success and -1 (with an exception set) on error.
Seesys.monitoring for descriptions of the events.
- intPyMonitoring_FirePyStartEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset)¶
Fire a
PY_STARTevent.
- intPyMonitoring_FirePyResumeEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset)¶
Fire a
PY_RESUMEevent.
- intPyMonitoring_FirePyReturnEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset,PyObject*retval)¶
Fire a
PY_RETURNevent.
- intPyMonitoring_FirePyYieldEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset,PyObject*retval)¶
Fire a
PY_YIELDevent.
- intPyMonitoring_FireCallEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset,PyObject*callable,PyObject*arg0)¶
Fire a
CALLevent.
- intPyMonitoring_FireLineEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset,intlineno)¶
Fire a
LINEevent.
- intPyMonitoring_FireJumpEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset,PyObject*target_offset)¶
Fire a
JUMPevent.
- intPyMonitoring_FireBranchLeftEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset,PyObject*target_offset)¶
Fire a
BRANCH_LEFTevent.
- intPyMonitoring_FireBranchRightEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset,PyObject*target_offset)¶
Fire a
BRANCH_RIGHTevent.
- intPyMonitoring_FireCReturnEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset,PyObject*retval)¶
Fire a
C_RETURNevent.
- intPyMonitoring_FirePyThrowEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset)¶
Fire a
PY_THROWevent with the current exception (as returned byPyErr_GetRaisedException()).
- intPyMonitoring_FireRaiseEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset)¶
Fire a
RAISEevent with the current exception (as returned byPyErr_GetRaisedException()).
- intPyMonitoring_FireCRaiseEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset)¶
Fire a
C_RAISEevent with the current exception (as returned byPyErr_GetRaisedException()).
- intPyMonitoring_FireReraiseEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset)¶
Fire a
RERAISEevent with the current exception (as returned byPyErr_GetRaisedException()).
- intPyMonitoring_FireExceptionHandledEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset)¶
Fire an
EXCEPTION_HANDLEDevent with the current exception (as returned byPyErr_GetRaisedException()).
- intPyMonitoring_FirePyUnwindEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset)¶
Fire a
PY_UNWINDevent with the current exception (as returned byPyErr_GetRaisedException()).
- intPyMonitoring_FireStopIterationEvent(PyMonitoringState*state,PyObject*codelike,int32_toffset,PyObject*value)¶
Fire a
STOP_ITERATIONevent. Ifvalueis an instance ofStopIteration, it is used. Otherwise,a newStopIterationinstance is created withvalueas its argument.
Managing the Monitoring State¶
Monitoring states can be managed with the help of monitoring scopes. A scopewould typically correspond to a Python function.
- intPyMonitoring_EnterScope(PyMonitoringState*state_array,uint64_t*version,constuint8_t*event_types,Py_ssize_tlength)¶
Enter a monitored scope.
event_typesis an array of the event IDs forevents that may be fired from the scope. For example, the ID of aPY_STARTevent is the valuePY_MONITORING_EVENT_PY_START, which is numerically equalto 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 ofthe event. The size ofevent_types(and hence also ofstate_array)is given inlength.The
versionargument is a pointer to a value which should be allocatedby the user together withstate_arrayand initialized to 0,and then set only byPyMonitoring_EnterScope()itself. It allows thisfunction 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 isentered. Scopes can be reentered, reusing the samestate_array andversion,in situations like when emulating a recursive Python function. When a code-like’sexecution is paused, such as when emulating a generator, the scope needs tobe exited and re-entered.The macros forevent_types are:
Macro
Event
- 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¶
- intPyMonitoring_ExitScope(void)¶
Exit the last scope that was entered with
PyMonitoring_EnterScope().
- intPY_MONITORING_IS_INSTRUMENTED_EVENT(uint8_tev)¶
Return true if the event corresponding to the event IDev isalocal event.
Added in version 3.13.
Deprecated since version 3.14:This function issoft deprecated.