Monitoring C API¶
Hinzugefügt in Version 3.13.
Eine Erweiterung muss möglicherweise mit dem Event-Monitoring-System interagieren. Das Abonnieren von Events und das Registrieren von Callbacks kann über die Python-API erfolgen, die in sys.monitoring verfügbar ist.
Generieren von Ausführungs-Events¶
Die folgenden Funktionen ermöglichen es einer Erweiterung, Monitoring-Events auszulösen, während sie die Ausführung von Python-Code emuliert. Jede dieser Funktionen akzeptiert eine PyMonitoringState-Struktur, die präzise Informationen über den Aktivierungsstatus von Events enthält, sowie Event-Argumente, die ein PyObject* darstellen, das das Code-Objekt, den Instruktions-Offset und manchmal zusätzliche, ereignisspezifische Argumente repräsentiert (Details zu den Signaturen der verschiedenen Event-Callbacks finden Sie in sys.monitoring). Das Argument codelike sollte eine Instanz von types.CodeType oder eines Typs sein, der ihn emuliert.
Die VM deaktiviert das Tracing beim Auslösen eines Events, daher ist es für Benutzercode nicht erforderlich, dies zu tun.
Monitoring-Funktionen sollten nicht mit einer gesetzten Ausnahme aufgerufen werden, außer denen, die unten als mit der aktuellen Ausnahme arbeitend aufgeführt sind.
-
type PyMonitoringState¶
Repräsentation des Zustands eines Event-Typs. Sie wird vom Benutzer alloziert, während ihre Inhalte von den nachfolgend beschriebenen Monitoring-API-Funktionen verwaltet werden.
Alle nachfolgenden Funktionen geben 0 bei Erfolg und -1 (mit gesetzter Ausnahme) bei Fehler zurück.
Siehe sys.monitoring für Beschreibungen der Events.
-
int PyMonitoring_FirePyStartEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
Löst ein
PY_START-Event aus.
-
int PyMonitoring_FirePyResumeEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
Löst ein
PY_RESUME-Event aus.
-
int PyMonitoring_FirePyReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *retval)¶
Löst ein
PY_RETURN-Event aus.
-
int PyMonitoring_FirePyYieldEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *retval)¶
Löst ein
PY_YIELD-Event aus.
-
int PyMonitoring_FireCallEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *callable, PyObject *arg0)¶
Löst ein
CALL-Event aus.
-
int PyMonitoring_FireLineEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, int lineno)¶
Löst ein
LINE-Event aus.
-
int PyMonitoring_FireJumpEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)¶
Löst ein
JUMP-Event aus.
-
int PyMonitoring_FireBranchLeftEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)¶
Löst ein
BRANCH_LEFT-Event aus.
-
int PyMonitoring_FireBranchRightEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *target_offset)¶
Löst ein
BRANCH_RIGHT-Event aus.
-
int PyMonitoring_FireCReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *retval)¶
Löst ein
C_RETURN-Event aus.
-
int PyMonitoring_FirePyThrowEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
Löst ein
PY_THROW-Event mit der aktuellen Ausnahme aus (wie vonPyErr_GetRaisedException()zurückgegeben).
-
int PyMonitoring_FireRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
Löst ein
RAISE-Event mit der aktuellen Ausnahme aus (wie vonPyErr_GetRaisedException()zurückgegeben).
-
int PyMonitoring_FireCRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
Löst ein
C_RAISE-Event mit der aktuellen Ausnahme aus (wie vonPyErr_GetRaisedException()zurückgegeben).
-
int PyMonitoring_FireReraiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
Löst ein
RERAISE-Event mit der aktuellen Ausnahme aus (wie vonPyErr_GetRaisedException()zurückgegeben).
-
int PyMonitoring_FireExceptionHandledEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
Löst ein
EXCEPTION_HANDLED-Event mit der aktuellen Ausnahme aus (wie vonPyErr_GetRaisedException()zurückgegeben).
-
int PyMonitoring_FirePyUnwindEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)¶
Löst ein
PY_UNWIND-Event mit der aktuellen Ausnahme aus (wie vonPyErr_GetRaisedException()zurückgegeben).
-
int PyMonitoring_FireStopIterationEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *value)¶
Löst ein
STOP_ITERATION-Event aus. Wennvalueeine Instanz vonStopIterationist, wird diese verwendet. Andernfalls wird eine neueStopIteration-Instanz mitvalueals Argument erstellt.
Verwaltung des Monitoring-Zustands¶
Monitoring-Zustände können mit Hilfe von Monitoring-Scopes verwaltet werden. Ein Scope entspricht typischerweise einer Python-Funktion.
-
int PyMonitoring_EnterScope(PyMonitoringState *state_array, uint64_t *version, const uint8_t *event_types, Py_ssize_t length)¶
Betritt einen überwachten Scope.
event_typesist ein Array der Event-IDs für Events, die aus dem Scope ausgelöst werden können. Zum Beispiel ist die ID einesPY_START-Events der WertPY_MONITORING_EVENT_PY_START, der numerisch dem Zweierlogarithmus vonsys.monitoring.events.PY_STARTentspricht.state_arrayist ein Array mit einem Monitoring-State-Eintrag für jedes Event inevent_types. Es wird vom Benutzer alloziert, aber vonPyMonitoring_EnterScope()mit Informationen über den Aktivierungsstatus des Events gefüllt. Die Größe vonevent_types(und damit auch vonstate_array) ist inlengthangegeben.Das Argument
versionist ein Zeiger auf einen Wert, der vom Benutzer zusammen mitstate_arrayalloziert und mit 0 initialisiert werden sollte, und dann nur vonPyMonitoring_EnterScope()selbst gesetzt wird. Es ermöglicht dieser Funktion zu ermitteln, ob sich die Event-Zustände seit dem vorherigen Aufruf geändert haben, und schnell zurückzukehren, wenn dies nicht der Fall ist.Die hier genannten Scopes sind lexikalische Scopes: eine Funktion, Klasse oder Methode.
PyMonitoring_EnterScope()sollte jedes Mal aufgerufen werden, wenn der lexikalische Scope betreten wird. Scopes können erneut betreten werden, wobei dieselben state_array und version wiederverwendet werden, in Situationen wie der Emulation einer rekursiven Python-Funktion. Wenn die Ausführung eines Code-Objekts pausiert wird, z. B. bei der Emulation eines Generators, muss der Scope verlassen und neu betreten werden.Die Makros für event_types sind
Makro
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¶
-
int PyMonitoring_ExitScope(void)¶
Verlässt den letzten Scope, der mit
PyMonitoring_EnterScope()betreten wurde.
-
int PY_MONITORING_IS_INSTRUMENTED_EVENT(uint8_t ev)¶
Gibt wahr zurück, wenn das Event, das der Event-ID ev entspricht, ein lokales Event ist.
Hinzugefügt in Version 3.13.
Seit Version 3.14 veraltet: Diese Funktion ist soft deprecated.