Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 35.2k
GH-103082: Implementation of PEP 669: Low Impact Monitoring for CPython#103083
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
e85d9106283ee84edb7b7852c40b416b31479719799896902f432a66fb29b3415a1ccd9abb3393ba6a39aa098959e5d87de52cbe66c8be7ec9e1e21e52e8d3f434ec7b680084e6e7cf15bbc83e7fe9a438b9f9969b026402cadf321f54d7743a3f3e3d436cf691bcf5f07be078b8f67ed0a22282a3a85ec3724abd64823c284d0b1b9e1f3b1440473825f42ace5ddb35740c47da83abecdb2bda0148fa3c5fb4f47fa431b25bbc615629a3e477cc5323b5f5edfc18c5566adbecfb17edc535f76d579d2e0982e5e0693423d6453e50ee2aeeacdca93f17ef14e7f6c37e44ebc5ece51e6e88921e2d9f22cb7579ac5a089a6d5fdec8c88741db6744ca6c3473a899aecd80d2e2e94d35d85aa0805b39edd3c9c40cb6611c7250d28f17165f5265c548e575f7d1415741dd70a1a4d580de62076d5f7b32d79662c16cd0139e951a93e764bf37f5faec770be1562b32a07585d6923ebcc42f7cfbc7ed366364fdb4860aee722fbba53b8718fbc897ec1c5edc6709e40a68fd9f81922d9a38029f41e738b7f439a40dada551d65495130644a031ec2155b7b2184289c0429ec6bf38e82fe16c43618a9821ae52505a08df63da91c324344168b34af07a080File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -58,12 +58,6 @@ typedef int (*Py_tracefunc)(PyObject *, PyFrameObject *, int, PyObject *); | ||
| #define PyTrace_C_RETURN 6 | ||
| #define PyTrace_OPCODE 7 | ||
| typedef struct { | ||
| PyCodeObject *code; // The code object for the bounds. May be NULL. | ||
| PyCodeAddressRange bounds; // Only valid if code != NULL. | ||
| } PyTraceInfo; | ||
| // Internal structure: you should not use it directly, but use public functions | ||
| // like PyThreadState_EnterTracing() and PyThreadState_LeaveTracing(). | ||
| typedef struct _PyCFrame { | ||
| @@ -77,7 +71,6 @@ typedef struct _PyCFrame { | ||
| * discipline and make sure that instances of this struct cannot | ||
| * accessed outside of their lifetime. | ||
| */ | ||
| uint8_t use_tracing; // 0 or 255 (or'ed into opcode, hence 8-bit type) | ||
| /* Pointer to the currently executing frame (it can be NULL) */ | ||
| struct _PyInterpreterFrame *current_frame; | ||
| struct _PyCFrame *previous; | ||
| @@ -157,7 +150,7 @@ struct _ts { | ||
| This is to prevent the actual trace/profile code from being recorded in | ||
| the trace/profile. */ | ||
| int tracing; | ||
| int tracing_what; /* The event currently being traced, if any. */ | ||
| int what_event; /* The event currently being monitored, if any. */ | ||
markshannon marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| /* Pointer to current _PyCFrame in the C stack frame of the currently, | ||
| * or most recently, executing _PyEval_EvalFrameDefault. */ | ||
| @@ -228,8 +221,6 @@ struct _ts { | ||
| /* Unique thread state id. */ | ||
| uint64_t id; | ||
| PyTraceInfo trace_info; | ||
| _PyStackChunk *datastack_chunk; | ||
| PyObject **datastack_top; | ||
| PyObject **datastack_limit; | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -19,6 +19,7 @@ struct _frame { | ||||||||||||||
| struct _PyInterpreterFrame *f_frame; /* points to the frame data */ | ||||||||||||||
| PyObject *f_trace; /* Trace function */ | ||||||||||||||
| int f_lineno; /* Current line number. Only valid if non-zero */ | ||||||||||||||
| int f_last_traced_line; /* The last line traced for this frame */ | ||||||||||||||
| char f_trace_lines; /* Emit per-line trace events? */ | ||||||||||||||
| char f_trace_opcodes; /* Emit per-opcode trace events? */ | ||||||||||||||
| char f_fast_as_locals; /* Have the fast locals of this frame been converted to a dict? */ | ||||||||||||||
| @@ -137,10 +138,16 @@ _PyFrame_GetLocalsArray(_PyInterpreterFrame *frame) | ||||||||||||||
| return frame->localsplus; | ||||||||||||||
| } | ||||||||||||||
| /* Fetches the stack pointer, and sets stacktop to -1. | ||||||||||||||
| Having stacktop <= 0 ensures that invalid | ||||||||||||||
| values are not visible to the cycle GC. | ||||||||||||||
| We choose -1 rather than 0 to assist debugging. */ | ||||||||||||||
Comment on lines
+142
to
+144
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
| ||||||||||||||
| static inline PyObject** | ||||||||||||||
| _PyFrame_GetStackPointer(_PyInterpreterFrame *frame) | ||||||||||||||
| { | ||||||||||||||
| return frame->localsplus+frame->stacktop; | ||||||||||||||
| PyObject **sp = frame->localsplus + frame->stacktop; | ||||||||||||||
| frame->stacktop = -1; | ||||||||||||||
| return sp; | ||||||||||||||
| } | ||||||||||||||
| static inline void | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| #ifndef Py_INTERNAL_INSTRUMENT_H | ||
| #define Py_INTERNAL_INSTRUMENT_H | ||
| #include "pycore_bitutils.h" // _Py_popcount32 | ||
| #include "pycore_frame.h" | ||
| #include "cpython/code.h" | ||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
| #define PY_MONITORING_TOOL_IDS 8 | ||
| /* Local events. | ||
| * These require bytecode instrumentation */ | ||
| #define PY_MONITORING_EVENT_PY_START 0 | ||
| #define PY_MONITORING_EVENT_PY_RESUME 1 | ||
| #define PY_MONITORING_EVENT_PY_RETURN 2 | ||
| #define PY_MONITORING_EVENT_PY_YIELD 3 | ||
| #define PY_MONITORING_EVENT_CALL 4 | ||
| #define PY_MONITORING_EVENT_LINE 5 | ||
| #define PY_MONITORING_EVENT_INSTRUCTION 6 | ||
| #define PY_MONITORING_EVENT_JUMP 7 | ||
| #define PY_MONITORING_EVENT_BRANCH 8 | ||
| #define PY_MONITORING_EVENT_STOP_ITERATION 9 | ||
| #define PY_MONITORING_INSTRUMENTED_EVENTS 10 | ||
| /* Other events, mainly exceptions */ | ||
| #define PY_MONITORING_EVENT_RAISE 10 | ||
| #define PY_MONITORING_EVENT_EXCEPTION_HANDLED 11 | ||
| #define PY_MONITORING_EVENT_PY_UNWIND 12 | ||
| #define PY_MONITORING_EVENT_PY_THROW 13 | ||
| /* Ancilliary events */ | ||
| #define PY_MONITORING_EVENT_C_RETURN 14 | ||
| #define PY_MONITORING_EVENT_C_RAISE 15 | ||
| typedef uint32_t _PyMonitoringEventSet; | ||
| /* Tool IDs */ | ||
| /* These are defined in PEP 669 for convenience to avoid clashes */ | ||
| #define PY_MONITORING_DEBUGGER_ID 0 | ||
| #define PY_MONITORING_COVERAGE_ID 1 | ||
| #define PY_MONITORING_PROFILER_ID 2 | ||
| #define PY_MONITORING_OPTIMIZER_ID 5 | ||
| /* Internal IDs used to suuport sys.setprofile() and sys.settrace() */ | ||
| #define PY_MONITORING_SYS_PROFILE_ID 6 | ||
| #define PY_MONITORING_SYS_TRACE_ID 7 | ||
| PyObject *_PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj); | ||
| int _PyMonitoring_SetEvents(int tool_id, _PyMonitoringEventSet events); | ||
| extern int | ||
| _Py_call_instrumentation(PyThreadState *tstate, int event, | ||
| _PyInterpreterFrame *frame, _Py_CODEUNIT *instr); | ||
| extern int | ||
| _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, | ||
| _Py_CODEUNIT *instr); | ||
| extern int | ||
| _Py_call_instrumentation_instruction( | ||
| PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr); | ||
| int | ||
| _Py_call_instrumentation_jump( | ||
| PyThreadState *tstate, int event, | ||
| _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *target); | ||
| extern int | ||
| _Py_call_instrumentation_arg(PyThreadState *tstate, int event, | ||
| _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg); | ||
| extern int | ||
| _Py_call_instrumentation_2args(PyThreadState *tstate, int event, | ||
| _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1); | ||
| extern void | ||
| _Py_call_instrumentation_exc0(PyThreadState *tstate, int event, | ||
| _PyInterpreterFrame *frame, _Py_CODEUNIT *instr); | ||
| extern void | ||
| _Py_call_instrumentation_exc2(PyThreadState *tstate, int event, | ||
| _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1); | ||
| extern int | ||
| _Py_Instrumentation_GetLine(PyCodeObject *code, int index); | ||
| extern PyObject _PyInstrumentation_MISSING; | ||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
| #endif /* !Py_INTERNAL_INSTRUMENT_H */ |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.