-
-
Notifications
You must be signed in to change notification settings - Fork 32k
gh-111997: C-API for signalling monitoring events #116413
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
102 commits
Select commit
Hold shift + click to select a range
b2d19c3
gh-111997: C-API for signalling monitoring events
iritkatriel 1b9487c
remove unnecessary events and add a basic test
iritkatriel 150011a
enhance test
iritkatriel ebc36b5
enable disable tests. api test functions return the new 'active' value
iritkatriel 1ad872c
Merge remote-tracking branch 'upstream/main' into monitoring-capi
iritkatriel 34179c1
update PCbuild
iritkatriel 3c9f8bb
use int
iritkatriel 344fd26
implement _PyMonitoringScopeBegin and add CodeLike type
iritkatriel ecaee5e
more tests
iritkatriel 5c68095
make functions public
iritkatriel 7661865
move tests from testinternalcapi to testcapi
iritkatriel 580a9f3
add include
iritkatriel 19a1f90
PyMonitoringScopeBegin --> PyMonitoring_BeginScope
iritkatriel 745a2b3
IF_ACTIVE --> _PyMonitoring_IF_ACTIVE
iritkatriel ba5e7e0
upate tests
iritkatriel aa19675
offset is int, event_types is const, remove "opaque"
iritkatriel 68aa352
PyMonitoring_FireLineEvent takes lineno as int
iritkatriel db4e3b8
add news
iritkatriel 99722f8
Merge remote-tracking branch 'upstream/main' into monitoring-capi
iritkatriel 445b19f
remove debug stuff
iritkatriel 33ce7aa
not static
iritkatriel cf6e20d
Revert "not static"
iritkatriel 89b05f1
ignore PyCodeLike_Type
iritkatriel 5f72725
typo
iritkatriel 6368b42
space to tab
iritkatriel e6d7c6a
skip test if no _testcapi
iritkatriel 58f2bcf
Code review comments
iritkatriel db5a286
remove unused
iritkatriel 0f329ae
Merge remote-tracking branch 'upstream/main' into monitoring-capi
iritkatriel 38346e8
add test with two events
iritkatriel 738921d
Merge remote-tracking branch 'upstream/main' into monitoring-capi
iritkatriel f5c40fc
add _PyMonitoring_EndScope
iritkatriel 95c5275
Begin/End --> Enter/Exit
iritkatriel 427e116
error checking
iritkatriel 3bc47df
review comments
iritkatriel 5f11cda
uint32_t --> int
iritkatriel e719e38
put ifdef back
iritkatriel be236b1
add opaque
iritkatriel 8c1eacf
always define the private versions. PyUnstable_ for the inlined
iritkatriel 23f579b
add tests for the Unstable version of the API
iritkatriel eee637e
tidy up declarations
iritkatriel 24cd7c4
Merge remote-tracking branch 'upstream/main' into monitoring-capi
iritkatriel 29c01e3
private versions are not in limited API
iritkatriel 0df7473
Merge remote-tracking branch 'upstream/main' into monitoring-capi
iritkatriel ef9a4a1
rename macro
iritkatriel dea138e
Merge branch 'main' into monitoring-capi
iritkatriel c0bcc22
update limited API
iritkatriel 48176fc
no need for two versions of EnterScope/ExitScope
iritkatriel c52dddc
Revert "update limited API"
iritkatriel 69cfe88
remove stable version. Rename Unstable functions
iritkatriel 20ce59f
Merge remote-tracking branch 'upstream/main' into monitoring-capi
iritkatriel 811402a
Delete Modules/_sqlite/connection-dd92fcfb.o.tmp
iritkatriel 86d2f67
Delete Modules/_testcapi/monitoring.c
iritkatriel e60f83f
Revert "Delete Modules/_testcapi/monitoring.c"
iritkatriel 8c052d3
Delete Modules/_sqlite/cursor-8e377591.o.tmp
iritkatriel e2f9f2f
Delete Python/pylifecycle-c98da669.o.tmp
iritkatriel 7b02a82
Delete Python/pystate-0cb7e25d.o.tmp
iritkatriel c605827
Merge branch 'main' into monitoring-capi
iritkatriel a6d45c4
Merge branch 'main' into monitoring-capi
iritkatriel e98827c
Merge branch 'main' into monitoring-capi
iritkatriel 5fdce63
remove a few bits
iritkatriel 21537da
Move non-limited API to Include/cpython/ (#56)
encukou 8eac91d
Merge branch 'main' into monitoring-capi
iritkatriel 1956867
Merge branch 'main' into monitoring-capi
iritkatriel 882a205
Merge remote-tracking branch 'upstream/main' into monitoring-capi
iritkatriel aaea28e
Petr's comments
iritkatriel 2f0a4d1
int -> int32_t for offset
iritkatriel 88e770f
give EnterScope/ExitScope a return value
iritkatriel 2bed2e3
add doc
iritkatriel 573fbf8
Merge remote-tracking branch 'upstream/main' into monitoring-capi
iritkatriel 85e9033
fix typo
iritkatriel 5162a03
update doc conf
iritkatriel 0438389
document PyMonitoringState
iritkatriel f53ceed
Merge branch 'main' into monitoring-capi
iritkatriel 75e5103
Update Doc/c-api/monitoring.rst
iritkatriel c7bd7f4
Petr's comments
iritkatriel 2c09788
update docs
iritkatriel 5936200
fix doc
iritkatriel 3f924e4
whitespace
iritkatriel d42b7c8
fix doc ref
iritkatriel d3a5dd5
fix ref
iritkatriel 0c4e65d
add title
iritkatriel a59568b
doc update
iritkatriel 71e6bd3
Merge branch 'main' into monitoring-capi
iritkatriel 1ed891d
Merge remote-tracking branch 'upstream/main' into monitoring-capi
iritkatriel 262977f
update doc per Petr's comments
iritkatriel 7d530b1
reentered
iritkatriel 45a7895
Apply suggestions from code review
iritkatriel cf9dfd0
whitespace
iritkatriel 03382bc
Merge branch 'main' into monitoring-capi
iritkatriel 3a6e583
add exceptions and disabling to doc
iritkatriel a704c4a
VM takes care of exception state for exception-related events
iritkatriel c7de609
bool -> int
iritkatriel e673b5a
exception events use 'current exception'
iritkatriel 5f00efb
update doc
iritkatriel 69e900e
raise on missing exception
iritkatriel 841eb6c
typo in doc
iritkatriel 2840f12
Petr's comments
iritkatriel c8499e5
Merge branch 'main' into monitoring-capi
iritkatriel aa6aa8a
Merge branch 'main' into monitoring-capi
iritkatriel 6c65373
Merge branch 'main' into monitoring-capi
iritkatriel bf84396
Merge branch 'main' into monitoring-capi
iritkatriel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,3 +25,4 @@ document the API functions in detail. | |
memory.rst | ||
objimpl.rst | ||
apiabiversion.rst | ||
monitoring.rst |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
iritkatriel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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. | ||
encukou marked this conversation as resolved.
Show resolved
Hide resolved
iritkatriel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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``. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.