diff --git a/Include/pystate.h b/Include/pystate.h index 1ff26268521..bfd3548fe2d 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -53,12 +53,16 @@ typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *); #define PyTrace_C_RETURN 6 typedef struct _ts { + /* See Python/ceval.c for comments explaining most fields */ struct _ts *next; PyInterpreterState *interp; struct _frame *frame; int recursion_depth; + /* 'tracing' keeps track of the execution depth when tracing/profiling. + This is to prevent the actual trace/profile code from being recorded in + the trace/profile. */ int tracing; int use_tracing; @@ -75,7 +79,7 @@ typedef struct _ts { PyObject *exc_value; PyObject *exc_traceback; - PyObject *dict; + PyObject *dict; /* Stores per-thread state */ /* tick_counter is incremented whenever the check_interval ticker * reaches zero. The purpose is to give a useful measure of the number diff --git a/Python/ceval.c b/Python/ceval.c index 459fd0d0b19..972061d0d6e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3284,10 +3284,12 @@ PyEval_SetProfile(Py_tracefunc func, PyObject *arg) Py_XINCREF(arg); tstate->c_profilefunc = NULL; tstate->c_profileobj = NULL; + /* Must make sure that tracing is not ignored if 'temp' is freed */ tstate->use_tracing = tstate->c_tracefunc != NULL; Py_XDECREF(temp); tstate->c_profilefunc = func; tstate->c_profileobj = arg; + /* Flag that tracing or profiling is turned on */ tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL); } @@ -3299,10 +3301,12 @@ PyEval_SetTrace(Py_tracefunc func, PyObject *arg) Py_XINCREF(arg); tstate->c_tracefunc = NULL; tstate->c_traceobj = NULL; + /* Must make sure that profiling is not ignored if 'temp' is freed */ tstate->use_tracing = tstate->c_profilefunc != NULL; Py_XDECREF(temp); tstate->c_tracefunc = func; tstate->c_traceobj = arg; + /* Flag that tracing or profiling is turned on */ tstate->use_tracing = ((func != NULL) || (tstate->c_profilefunc != NULL)); }