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 von PyErr_GetRaisedException() zurückgegeben).

int PyMonitoring_FireRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)

Löst ein RAISE-Event mit der aktuellen Ausnahme aus (wie von PyErr_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 von PyErr_GetRaisedException() zurückgegeben).

int PyMonitoring_FireReraiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)

Löst ein RERAISE-Event mit der aktuellen Ausnahme aus (wie von PyErr_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 von PyErr_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 von PyErr_GetRaisedException() zurückgegeben).

int PyMonitoring_FireStopIterationEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *value)

Löst ein STOP_ITERATION-Event aus. Wenn value eine Instanz von StopIteration ist, wird diese verwendet. Andernfalls wird eine neue StopIteration-Instanz mit value als 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_types ist ein Array der Event-IDs für Events, die aus dem Scope ausgelöst werden können. Zum Beispiel ist die ID eines PY_START-Events der Wert PY_MONITORING_EVENT_PY_START, der numerisch dem Zweierlogarithmus von sys.monitoring.events.PY_START entspricht. state_array ist ein Array mit einem Monitoring-State-Eintrag für jedes Event in event_types. Es wird vom Benutzer alloziert, aber von PyMonitoring_EnterScope() mit Informationen über den Aktivierungsstatus des Events gefüllt. Die Größe von event_types (und damit auch von state_array) ist in length angegeben.

Das Argument version ist ein Zeiger auf einen Wert, der vom Benutzer zusammen mit state_array alloziert und mit 0 initialisiert werden sollte, und dann nur von PyMonitoring_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

BRANCH_LEFT

PY_MONITORING_EVENT_BRANCH_RIGHT

BRANCH_RIGHT

PY_MONITORING_EVENT_CALL

CALL

PY_MONITORING_EVENT_C_RAISE

C_RAISE

PY_MONITORING_EVENT_C_RETURN

C_RETURN

PY_MONITORING_EVENT_EXCEPTION_HANDLED

EXCEPTION_HANDLED

PY_MONITORING_EVENT_INSTRUCTION

INSTRUCTION

PY_MONITORING_EVENT_JUMP

JUMP

PY_MONITORING_EVENT_LINE

LINE

PY_MONITORING_EVENT_PY_RESUME

PY_RESUME

PY_MONITORING_EVENT_PY_RETURN

PY_RETURN

PY_MONITORING_EVENT_PY_START

PY_START

PY_MONITORING_EVENT_PY_THROW

PY_THROW

PY_MONITORING_EVENT_PY_UNWIND

PY_UNWIND

PY_MONITORING_EVENT_PY_YIELD

PY_YIELD

PY_MONITORING_EVENT_RAISE

RAISE

PY_MONITORING_EVENT_RERAISE

RERAISE

PY_MONITORING_EVENT_STOP_ITERATION

STOP_ITERATION

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.