bpo-43760: Add PyThreadState_EnterTracing() (GH-28542)

Add PyThreadState_EnterTracing() and PyThreadState_LeaveTracing()
functions to the limited C API to suspend and resume tracing and
profiling.

Add an unit test on the PyThreadState C API to _testcapi.

Add also internal _PyThreadState_DisableTracing() and
_PyThreadState_ResetTracing().
This commit is contained in:
Victor Stinner 2021-10-15 16:06:30 +02:00 committed by GitHub
parent 354c35220d
commit 547d26aa08
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 146 additions and 25 deletions

View file

@ -6187,7 +6187,7 @@ call_trace(Py_tracefunc func, PyObject *obj,
if (tstate->tracing)
return 0;
tstate->tracing++;
tstate->cframe->use_tracing = 0;
_PyThreadState_DisableTracing(tstate);
PyFrameObject *f = _PyFrame_GetFrameObject(frame);
if (f == NULL) {
return -1;
@ -6201,8 +6201,7 @@ call_trace(Py_tracefunc func, PyObject *obj,
}
result = func(obj, f, what, arg);
f->f_lineno = 0;
tstate->cframe->use_tracing = ((tstate->c_tracefunc != NULL)
|| (tstate->c_profilefunc != NULL)) ? 255 : 0;
_PyThreadState_ResetTracing(tstate);
tstate->tracing--;
return result;
}
@ -6216,8 +6215,7 @@ _PyEval_CallTracing(PyObject *func, PyObject *args)
PyObject *result;
tstate->tracing = 0;
tstate->cframe->use_tracing = ((tstate->c_tracefunc != NULL)
|| (tstate->c_profilefunc != NULL)) ? 255 : 0;
_PyThreadState_ResetTracing(tstate);
result = PyObject_Call(func, args, NULL);
tstate->tracing = save_tracing;
tstate->cframe->use_tracing = save_use_tracing;
@ -6274,7 +6272,7 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
tstate->c_profilefunc = NULL;
tstate->c_profileobj = NULL;
/* Must make sure that tracing is not ignored if 'profileobj' is freed */
tstate->cframe->use_tracing = tstate->c_tracefunc != NULL;
_PyThreadState_ResetTracing(tstate);
Py_XDECREF(profileobj);
Py_XINCREF(arg);
@ -6282,7 +6280,7 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
tstate->c_profilefunc = func;
/* Flag that tracing or profiling is turned on */
tstate->cframe->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL) ? 255 : 0;
_PyThreadState_ResetTracing(tstate);
return 0;
}
@ -6315,7 +6313,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
tstate->c_tracefunc = NULL;
tstate->c_traceobj = NULL;
/* Must make sure that profiling is not ignored if 'traceobj' is freed */
tstate->cframe->use_tracing = (tstate->c_profilefunc != NULL) ? 255 : 0;
_PyThreadState_ResetTracing(tstate);
Py_XDECREF(traceobj);
Py_XINCREF(arg);
@ -6323,8 +6321,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
tstate->c_tracefunc = func;
/* Flag that tracing or profiling is turned on */
tstate->cframe->use_tracing = ((func != NULL)
|| (tstate->c_profilefunc != NULL)) ? 255 : 0;
_PyThreadState_ResetTracing(tstate);
return 0;
}