diff options
Diffstat (limited to 'Python/legacy_tracing.c')
-rw-r--r-- | Python/legacy_tracing.c | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/Python/legacy_tracing.c b/Python/legacy_tracing.c index ddc727113af..ccbb3eb3f7c 100644 --- a/Python/legacy_tracing.c +++ b/Python/legacy_tracing.c @@ -117,6 +117,35 @@ sys_profile_call_or_return( Py_RETURN_NONE; } +int +_PyEval_SetOpcodeTrace( + PyFrameObject *frame, + bool enable +) { + assert(frame != NULL); + assert(PyCode_Check(frame->f_frame->f_executable)); + + PyCodeObject *code = (PyCodeObject *)frame->f_frame->f_executable; + _PyMonitoringEventSet events = 0; + + if (_PyMonitoring_GetLocalEvents(code, PY_MONITORING_SYS_TRACE_ID, &events) < 0) { + return -1; + } + + if (enable) { + if (events & (1 << PY_MONITORING_EVENT_INSTRUCTION)) { + return 0; + } + events |= (1 << PY_MONITORING_EVENT_INSTRUCTION); + } else { + if (!(events & (1 << PY_MONITORING_EVENT_INSTRUCTION))) { + return 0; + } + events &= (~(1 << PY_MONITORING_EVENT_INSTRUCTION)); + } + return _PyMonitoring_SetLocalEvents(code, PY_MONITORING_SYS_TRACE_ID, events); +} + static PyObject * call_trace_func(_PyLegacyEventHandler *self, PyObject *arg) { @@ -130,6 +159,12 @@ call_trace_func(_PyLegacyEventHandler *self, PyObject *arg) "Missing frame when calling trace function."); return NULL; } + if (frame->f_trace_opcodes) { + if (_PyEval_SetOpcodeTrace(frame, true) != 0) { + return NULL; + } + } + Py_INCREF(frame); int err = tstate->c_tracefunc(tstate->c_traceobj, frame, self->event, arg); Py_DECREF(frame); @@ -230,11 +265,14 @@ sys_trace_instruction_func( "Missing frame when calling trace function."); return NULL; } - if (!frame->f_trace_opcodes) { + PyThreadState *tstate = _PyThreadState_GET(); + if (!tstate->c_tracefunc || !frame->f_trace_opcodes) { + if (_PyEval_SetOpcodeTrace(frame, false) != 0) { + return NULL; + } Py_RETURN_NONE; } Py_INCREF(frame); - PyThreadState *tstate = _PyThreadState_GET(); int err = tstate->c_tracefunc(tstate->c_traceobj, frame, self->event, Py_None); frame->f_lineno = 0; Py_DECREF(frame); @@ -531,9 +569,15 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) (1 << PY_MONITORING_EVENT_PY_UNWIND) | (1 << PY_MONITORING_EVENT_PY_THROW) | (1 << PY_MONITORING_EVENT_STOP_ITERATION) | (1 << PY_MONITORING_EVENT_EXCEPTION_HANDLED); - if (tstate->interp->f_opcode_trace_set) { - events |= (1 << PY_MONITORING_EVENT_INSTRUCTION); + + PyFrameObject* frame = PyEval_GetFrame(); + if (frame->f_trace_opcodes) { + int ret = _PyEval_SetOpcodeTrace(frame, true); + if (ret != 0) { + return ret; + } } } + return _PyMonitoring_SetEvents(PY_MONITORING_SYS_TRACE_ID, events); } |