@@ -117,6 +117,35 @@ sys_profile_call_or_return(
117117 Py_RETURN_NONE ;
118118}
119119
120+ int
121+ _PyEval_SetOpcodeTrace (
122+ PyFrameObject * frame ,
123+ bool enable
124+ ) {
125+ assert (frame != NULL );
126+ assert (PyCode_Check (frame -> f_frame -> f_executable ));
127+
128+ PyCodeObject * code = (PyCodeObject * )frame -> f_frame -> f_executable ;
129+ _PyMonitoringEventSet events = 0 ;
130+
131+ if (_PyMonitoring_GetLocalEvents (code , PY_MONITORING_SYS_TRACE_ID , & events ) < 0 ) {
132+ return -1 ;
133+ }
134+
135+ if (enable ) {
136+ if (events & (1 << PY_MONITORING_EVENT_INSTRUCTION )) {
137+ return 0 ;
138+ }
139+ events |= (1 << PY_MONITORING_EVENT_INSTRUCTION );
140+ } else {
141+ if (!(events & (1 << PY_MONITORING_EVENT_INSTRUCTION ))) {
142+ return 0 ;
143+ }
144+ events &= (~(1 << PY_MONITORING_EVENT_INSTRUCTION ));
145+ }
146+ return _PyMonitoring_SetLocalEvents (code , PY_MONITORING_SYS_TRACE_ID , events );
147+ }
148+
120149static PyObject *
121150call_trace_func (_PyLegacyEventHandler * self , PyObject * arg )
122151{
@@ -130,6 +159,12 @@ call_trace_func(_PyLegacyEventHandler *self, PyObject *arg)
130159 "Missing frame when calling trace function." );
131160 return NULL ;
132161 }
162+ if (frame -> f_trace_opcodes ) {
163+ if (_PyEval_SetOpcodeTrace (frame , true) != 0 ) {
164+ return NULL ;
165+ }
166+ }
167+
133168 Py_INCREF (frame );
134169 int err = tstate -> c_tracefunc (tstate -> c_traceobj , frame , self -> event , arg );
135170 Py_DECREF (frame );
@@ -230,11 +265,14 @@ sys_trace_instruction_func(
230265 "Missing frame when calling trace function." );
231266 return NULL ;
232267 }
233- if (!frame -> f_trace_opcodes ) {
268+ PyThreadState * tstate = _PyThreadState_GET ();
269+ if (!tstate -> c_tracefunc || !frame -> f_trace_opcodes ) {
270+ if (_PyEval_SetOpcodeTrace (frame , false) != 0 ) {
271+ return NULL ;
272+ }
234273 Py_RETURN_NONE ;
235274 }
236275 Py_INCREF (frame );
237- PyThreadState * tstate = _PyThreadState_GET ();
238276 int err = tstate -> c_tracefunc (tstate -> c_traceobj , frame , self -> event , Py_None );
239277 frame -> f_lineno = 0 ;
240278 Py_DECREF (frame );
@@ -531,9 +569,15 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
531569 (1 << PY_MONITORING_EVENT_PY_UNWIND ) | (1 << PY_MONITORING_EVENT_PY_THROW ) |
532570 (1 << PY_MONITORING_EVENT_STOP_ITERATION ) |
533571 (1 << PY_MONITORING_EVENT_EXCEPTION_HANDLED );
534- if (tstate -> interp -> f_opcode_trace_set ) {
535- events |= (1 << PY_MONITORING_EVENT_INSTRUCTION );
572+
573+ PyFrameObject * frame = PyEval_GetFrame ();
574+ if (frame -> f_trace_opcodes ) {
575+ int ret = _PyEval_SetOpcodeTrace (frame , true);
576+ if (ret != 0 ) {
577+ return ret ;
578+ }
536579 }
537580 }
581+
538582 return _PyMonitoring_SetEvents (PY_MONITORING_SYS_TRACE_ID , events );
539583}
0 commit comments