summaryrefslogtreecommitdiffstats
path: root/Doc/c-api
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2024-05-04 08:23:50 (GMT)
committerGitHub <noreply@github.com>2024-05-04 08:23:50 (GMT)
commit85af78996117dbe8ad45716633a3d6c39ff7bab2 (patch)
tree31c8836d1a3f177c84100136d55decf7d8e29983 /Doc/c-api
parentda2cfc4cb6b756b819b45bf34dd735c27b74d803 (diff)
downloadcpython-85af78996117dbe8ad45716633a3d6c39ff7bab2.zip
cpython-85af78996117dbe8ad45716633a3d6c39ff7bab2.tar.gz
cpython-85af78996117dbe8ad45716633a3d6c39ff7bab2.tar.bz2
gh-111997: C-API for signalling monitoring events (#116413)
Diffstat (limited to 'Doc/c-api')
-rw-r--r--Doc/c-api/index.rst1
-rw-r--r--Doc/c-api/monitoring.rst164
2 files changed, 165 insertions, 0 deletions
diff --git a/Doc/c-api/index.rst b/Doc/c-api/index.rst
index 9a8f150..ba56b03 100644
--- a/Doc/c-api/index.rst
+++ b/Doc/c-api/index.rst
@@ -25,3 +25,4 @@ document the API functions in detail.
memory.rst
objimpl.rst
apiabiversion.rst
+ monitoring.rst
diff --git a/Doc/c-api/monitoring.rst b/Doc/c-api/monitoring.rst
new file mode 100644
index 0000000..763ec8e
--- /dev/null
+++ b/Doc/c-api/monitoring.rst
@@ -0,0 +1,164 @@
+.. highlight:: c
+
+.. _monitoring:
+
+Monitorong C API
+================
+
+Added in version 3.13.
+
+An extension may need to interact with the event monitoring system. Subscribing
+to events and registering callbacks can be done via the Python API exposed in
+:mod:`sys.monitoring`.
+
+Generating Execution Events
+===========================
+
+The functions below make it possible for an extension to fire monitoring
+events as it emulates the execution of Python code. Each of these functions
+accepts a ``PyMonitoringState`` struct which contains concise information
+about the activation state of events, as well as the event arguments, which
+include a ``PyObject*`` representing the code object, the instruction offset
+and sometimes additional, event-specific arguments (see :mod:`sys.monitoring`
+for details about the signatures of the different event callbacks).
+The ``codelike`` argument should be an instance of :class:`types.CodeType`
+or of a type that emulates it.
+
+The VM disables tracing when firing an event, so there is no need for user
+code to do that.
+
+Monitoring functions should not be called with an exception set,
+except those listed below as working with the current exception.
+
+.. c:type:: PyMonitoringState
+
+ Representation of the state of an event type. It is allocated by the user
+ while 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.
+
+See :mod:`sys.monitoring` for descriptions of the events.
+
+.. c:function:: int PyMonitoring_FirePyStartEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
+
+ Fire a ``PY_START`` event.
+
+
+.. c:function:: int PyMonitoring_FirePyResumeEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
+
+ Fire a ``PY_RESUME`` event.
+
+
+.. c:function:: int PyMonitoring_FirePyReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject* retval)
+
+ Fire a ``PY_RETURN`` event.
+
+
+.. c:function:: int PyMonitoring_FirePyYieldEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject* retval)
+
+ Fire a ``PY_YIELD`` event.
+
+
+.. c:function:: int PyMonitoring_FireCallEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject* callable, PyObject *arg0)
+
+ Fire a ``CALL`` event.
+
+
+.. c:function:: int PyMonitoring_FireLineEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, int lineno)
+
+ Fire a ``LINE`` event.
+
+
+.. c:function:: int PyMonitoring_FireJumpEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)
+
+ Fire a ``JUMP`` event.
+
+
+.. c:function:: int PyMonitoring_FireBranchEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)
+
+ Fire a ``BRANCH`` event.
+
+
+.. c:function:: int PyMonitoring_FireCReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *retval)
+
+ Fire a ``C_RETURN`` event.
+
+
+.. c:function:: int PyMonitoring_FirePyThrowEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
+
+ Fire a ``PY_THROW`` event with the current exception (as returned by
+ :c:func:`PyErr_GetRaisedException`).
+
+
+.. c:function:: int PyMonitoring_FireRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
+
+ Fire a ``RAISE`` event with the current exception (as returned by
+ :c:func:`PyErr_GetRaisedException`).
+
+
+.. c:function:: int PyMonitoring_FireCRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
+
+ Fire a ``C_RAISE`` event with the current exception (as returned by
+ :c:func:`PyErr_GetRaisedException`).
+
+
+.. c:function:: int PyMonitoring_FireReraiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
+
+ Fire a ``RERAISE`` event with the current exception (as returned by
+ :c:func:`PyErr_GetRaisedException`).
+
+
+.. c:function:: int PyMonitoring_FireExceptionHandledEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
+
+ Fire an ``EXCEPTION_HANDLED`` event with the current exception (as returned by
+ :c:func:`PyErr_GetRaisedException`).
+
+
+.. c:function:: int PyMonitoring_FirePyUnwindEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
+
+ Fire a ``PY_UNWIND`` event with the current exception (as returned by
+ :c:func:`PyErr_GetRaisedException`).
+
+
+.. c:function:: int PyMonitoring_FireStopIterationEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
+
+ Fire a ``STOP_ITERATION`` event with the current exception (as returned by
+ :c:func:`PyErr_GetRaisedException`).
+
+
+Managing the Monitoring State
+-----------------------------
+
+Monitoring states can be managed with the help of monitoring scopes. A scope
+would typically correspond to a python function.
+
+.. :c:function:: int PyMonitoring_EnterScope(PyMonitoringState *state_array, uint64_t *version, const uint8_t *event_types, Py_ssize_t length)
+
+ Enter a monitored scope. ``event_types`` is an array of the event IDs for
+ events that may be fired from the scope. For example, the ID of a ``PY_START``
+ event is the value ``PY_MONITORING_EVENT_PY_START``, which is numerically equal
+ to the base-2 logarithm of ``sys.monitoring.events.PY_START``.
+ ``state_array`` is an array with a monitoring state entry for each event in
+ ``event_types``, it is allocated by the user but populated by
+ ``PyMonitoring_EnterScope`` with information about the activation state of
+ the event. The size of ``event_types`` (and hence also of ``state_array``)
+ is given in ``length``.
+
+ The ``version`` argument is a pointer to a value which should be allocated
+ by the user together with ``state_array`` and initialized to 0,
+ and then set only by ``PyMonitoring_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.
+
+
+.. :c:function:: int PyMonitoring_ExitScope(void)
+
+ Exit the last scope that was entered with ``PyMonitoring_EnterScope``.