Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions Doc/library/sys.monitoring.rst
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ Local events
''''''''''''

Local events are associated with normal execution of the program and happen
at clearly defined locations. All local events can be disabled.
The local events are:
at clearly defined locations. All local events can be disabled
per location. The local events are:

* :monitoring-event:`PY_START`
* :monitoring-event:`PY_RESUME`
Expand All @@ -205,6 +205,8 @@ Using :monitoring-event:`BRANCH_LEFT` and :monitoring-event:`BRANCH_RIGHT`
events will give much better performance as they can be disabled
independently.

.. _monitoring-ancillary-events:

Ancillary events
''''''''''''''''

Expand All @@ -226,14 +228,20 @@ Other events
''''''''''''

Other events are not necessarily tied to a specific location in the
program and cannot be individually disabled via :data:`DISABLE`.
program and cannot be individually disabled per location.

The other events that can be monitored are:

* :monitoring-event:`PY_THROW`
* :monitoring-event:`PY_UNWIND`
* :monitoring-event:`RAISE`
* :monitoring-event:`EXCEPTION_HANDLED`
* :monitoring-event:`RERAISE`

.. versionchanged:: 3.15
Other events can now be turned on and disabled on a per code object
basis. Returning :data:`DISABLE` from a callback disables the event
for the entire code object (for the current tool).


The STOP_ITERATION event
Expand All @@ -247,8 +255,7 @@ raise an exception unless it would be visible to other code.

To allow tools to monitor for real exceptions without slowing down generators
and coroutines, the :monitoring-event:`STOP_ITERATION` event is provided.
:monitoring-event:`STOP_ITERATION` can be locally disabled, unlike
:monitoring-event:`RAISE`.
:monitoring-event:`STOP_ITERATION` can be locally disabled.

Note that the :monitoring-event:`STOP_ITERATION` event and the
:monitoring-event:`RAISE` event for a :exc:`StopIteration` exception are
Expand Down Expand Up @@ -314,15 +321,14 @@ location by returning :data:`sys.monitoring.DISABLE` from a callback function.
This does not change which events are set, or any other code locations for the
same event.

Disabling events for specific locations is very important for high
performance monitoring. For example, a program can be run under a
debugger with no overhead if the debugger disables all monitoring
except for a few breakpoints.
:ref:`Other events <monitoring-event-global>` can be disabled on a per code
object basis by returning :data:`sys.monitoring.DISABLE` from a callback
function. This disables the event for the entire code object (for the current
tool).

If :data:`DISABLE` is returned by a callback for a
:ref:`global event <monitoring-event-global>`, :exc:`ValueError` will be raised
by the interpreter in a non-specific location (that is, no traceback will be
provided).
Disabling events for specific locations is very important for high performance
monitoring. For example, a program can be run under a debugger with no overhead
if the debugger disables all monitoring except for a few breakpoints.

.. function:: restart_events() -> None

Expand Down
12 changes: 8 additions & 4 deletions Include/cpython/monitoring.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,20 @@ extern "C" {
#define PY_MONITORING_EVENT_STOP_ITERATION 10

#define PY_MONITORING_IS_INSTRUMENTED_EVENT(ev) \
((ev) < _PY_MONITORING_LOCAL_EVENTS)
((ev) <= PY_MONITORING_EVENT_STOP_ITERATION)

/* Other events, mainly exceptions */
/* Other events, mainly exceptions.
* These can now be turned on and disabled on a per code object basis. */

#define PY_MONITORING_EVENT_RAISE 11
#define PY_MONITORING_EVENT_PY_UNWIND 11
#define PY_MONITORING_EVENT_EXCEPTION_HANDLED 12
#define PY_MONITORING_EVENT_PY_UNWIND 13
#define PY_MONITORING_EVENT_RAISE 13
#define PY_MONITORING_EVENT_PY_THROW 14
#define PY_MONITORING_EVENT_RERAISE 15

#define _PY_MONITORING_IS_UNGROUPED_EVENT(ev) \
((ev) < _PY_MONITORING_UNGROUPED_EVENTS)


/* Ancillary events */

Expand Down
2 changes: 1 addition & 1 deletion Include/internal/pycore_ceval.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ PyObject * _PyEval_ImportNameWithImport(
PyAPI_FUNC(PyObject *)_PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, Py_ssize_t nargs, PyObject *kwargs);
PyAPI_FUNC(PyObject *)_PyEval_MatchKeys(PyThreadState *tstate, PyObject *map, PyObject *keys);
PyAPI_FUNC(void) _PyEval_MonitorRaise(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr);
PyAPI_FUNC(bool) _PyEval_NoToolsForUnwind(PyThreadState *tstate);
PyAPI_FUNC(bool) _PyEval_NoToolsForUnwind(PyThreadState *tstate, _PyInterpreterFrame *frame);
PyAPI_FUNC(int) _PyEval_UnpackIterableStackRef(PyThreadState *tstate, PyObject *v, int argcnt, int argcntafter, _PyStackRef *sp);
PyAPI_FUNC(void) _PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame *frame);
PyAPI_FUNC(PyObject **) _PyObjectArray_FromStackRefArray(_PyStackRef *input, Py_ssize_t nargs, PyObject **scratch);
Expand Down
7 changes: 3 additions & 4 deletions Include/internal/pycore_instruments.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,15 @@ PyAPI_DATA(PyObject) _PyInstrumentation_DISABLE;

/* Total tool ids available */
#define PY_MONITORING_TOOL_IDS 8
/* Count of all local monitoring events */
#define _PY_MONITORING_LOCAL_EVENTS 11
/* Count of all "real" monitoring events (not derived from other events) */
/* Count of all "real" monitoring events (not derived from other events).
* "Other" events can now be turned on/disabled per code object. */
#define _PY_MONITORING_UNGROUPED_EVENTS 16
/* Count of all monitoring events */
#define _PY_MONITORING_EVENTS 19

/* Tables of which tools are active for each monitored event. */
typedef struct _Py_LocalMonitors {
uint8_t tools[_PY_MONITORING_LOCAL_EVENTS];
uint8_t tools[_PY_MONITORING_UNGROUPED_EVENTS];
} _Py_LocalMonitors;

typedef struct _Py_GlobalMonitors {
Expand Down
Loading
Loading