bpo-45923: Decouple suspension of tracing from tracing flag. (GH-31908)

This commit is contained in:
Mark Shannon 2022-03-15 17:06:21 +00:00 committed by GitHub
parent a8c728b8b7
commit 099f756141
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 39 deletions

View File

@ -139,14 +139,9 @@ PyAPI_FUNC(void) _PyThreadState_DeleteExcept(
_PyRuntimeState *runtime, _PyRuntimeState *runtime,
PyThreadState *tstate); PyThreadState *tstate);
static inline void
_PyThreadState_PauseTracing(PyThreadState *tstate)
{
tstate->cframe->use_tracing = 0;
}
static inline void static inline void
_PyThreadState_ResumeTracing(PyThreadState *tstate) _PyThreadState_UpdateTracingState(PyThreadState *tstate)
{ {
int use_tracing = (tstate->c_tracefunc != NULL int use_tracing = (tstate->c_tracefunc != NULL
|| tstate->c_profilefunc != NULL); || tstate->c_profilefunc != NULL);

View File

@ -5439,10 +5439,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
} }
#if USE_COMPUTED_GOTOS #if USE_COMPUTED_GOTOS
TARGET_DO_TRACING: { TARGET_DO_TRACING:
#else #else
case DO_TRACING: { case DO_TRACING:
#endif #endif
{
if (tstate->tracing == 0) {
int instr_prev = skip_backwards_over_extended_args(frame->f_code, frame->f_lasti); int instr_prev = skip_backwards_over_extended_args(frame->f_code, frame->f_lasti);
frame->f_lasti = INSTR_OFFSET(); frame->f_lasti = INSTR_OFFSET();
TRACING_NEXTOPARG(); TRACING_NEXTOPARG();
@ -5482,12 +5484,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
frame->stacktop = -1; frame->stacktop = -1;
} }
} }
}
TRACING_NEXTOPARG(); TRACING_NEXTOPARG();
PRE_DISPATCH_GOTO(); PRE_DISPATCH_GOTO();
DISPATCH_GOTO(); DISPATCH_GOTO();
} }
#if USE_COMPUTED_GOTOS #if USE_COMPUTED_GOTOS
_unknown_opcode: _unknown_opcode:
#else #else
@ -6673,27 +6675,38 @@ initialize_trace_info(PyTraceInfo *trace_info, _PyInterpreterFrame *frame)
} }
} }
void
PyThreadState_EnterTracing(PyThreadState *tstate)
{
tstate->tracing++;
}
void
PyThreadState_LeaveTracing(PyThreadState *tstate)
{
tstate->tracing--;
}
static int static int
call_trace(Py_tracefunc func, PyObject *obj, call_trace(Py_tracefunc func, PyObject *obj,
PyThreadState *tstate, _PyInterpreterFrame *frame, PyThreadState *tstate, _PyInterpreterFrame *frame,
int what, PyObject *arg) int what, PyObject *arg)
{ {
int result; int result;
if (tstate->tracing) if (tstate->tracing) {
return 0; return 0;
tstate->tracing++; }
_PyThreadState_PauseTracing(tstate);
PyFrameObject *f = _PyFrame_GetFrameObject(frame); PyFrameObject *f = _PyFrame_GetFrameObject(frame);
if (f == NULL) { if (f == NULL) {
return -1; return -1;
} }
PyThreadState_EnterTracing(tstate);
assert (frame->f_lasti >= 0); assert (frame->f_lasti >= 0);
initialize_trace_info(&tstate->trace_info, frame); initialize_trace_info(&tstate->trace_info, frame);
f->f_lineno = _PyCode_CheckLineNumber(frame->f_lasti*sizeof(_Py_CODEUNIT), &tstate->trace_info.bounds); f->f_lineno = _PyCode_CheckLineNumber(frame->f_lasti*sizeof(_Py_CODEUNIT), &tstate->trace_info.bounds);
result = func(obj, f, what, arg); result = func(obj, f, what, arg);
f->f_lineno = 0; f->f_lineno = 0;
_PyThreadState_ResumeTracing(tstate); PyThreadState_LeaveTracing(tstate);
tstate->tracing--;
return result; return result;
} }
@ -6706,7 +6719,6 @@ _PyEval_CallTracing(PyObject *func, PyObject *args)
PyObject *result; PyObject *result;
tstate->tracing = 0; tstate->tracing = 0;
_PyThreadState_ResumeTracing(tstate);
result = PyObject_Call(func, args, NULL); result = PyObject_Call(func, args, NULL);
tstate->tracing = save_tracing; tstate->tracing = save_tracing;
tstate->cframe->use_tracing = save_use_tracing; tstate->cframe->use_tracing = save_use_tracing;
@ -6773,7 +6785,7 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
tstate->c_profilefunc = NULL; tstate->c_profilefunc = NULL;
tstate->c_profileobj = NULL; tstate->c_profileobj = NULL;
/* Must make sure that tracing is not ignored if 'profileobj' is freed */ /* Must make sure that tracing is not ignored if 'profileobj' is freed */
_PyThreadState_ResumeTracing(tstate); _PyThreadState_UpdateTracingState(tstate);
Py_XDECREF(profileobj); Py_XDECREF(profileobj);
Py_XINCREF(arg); Py_XINCREF(arg);
@ -6781,7 +6793,7 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
tstate->c_profilefunc = func; tstate->c_profilefunc = func;
/* Flag that tracing or profiling is turned on */ /* Flag that tracing or profiling is turned on */
_PyThreadState_ResumeTracing(tstate); _PyThreadState_UpdateTracingState(tstate);
return 0; return 0;
} }
@ -6814,7 +6826,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
tstate->c_tracefunc = NULL; tstate->c_tracefunc = NULL;
tstate->c_traceobj = NULL; tstate->c_traceobj = NULL;
/* Must make sure that profiling is not ignored if 'traceobj' is freed */ /* Must make sure that profiling is not ignored if 'traceobj' is freed */
_PyThreadState_ResumeTracing(tstate); _PyThreadState_UpdateTracingState(tstate);
Py_XDECREF(traceobj); Py_XDECREF(traceobj);
Py_XINCREF(arg); Py_XINCREF(arg);
@ -6822,7 +6834,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
tstate->c_tracefunc = func; tstate->c_tracefunc = func;
/* Flag that tracing or profiling is turned on */ /* Flag that tracing or profiling is turned on */
_PyThreadState_ResumeTracing(tstate); _PyThreadState_UpdateTracingState(tstate);
return 0; return 0;
} }

View File

@ -1333,23 +1333,6 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
return 0; return 0;
} }
void
PyThreadState_EnterTracing(PyThreadState *tstate)
{
tstate->tracing++;
_PyThreadState_PauseTracing(tstate);
}
void
PyThreadState_LeaveTracing(PyThreadState *tstate)
{
tstate->tracing--;
_PyThreadState_ResumeTracing(tstate);
}
/* Routines for advanced debuggers, requested by David Beazley. /* Routines for advanced debuggers, requested by David Beazley.
Don't use unless you know what you are doing! */ Don't use unless you know what you are doing! */