mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
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:
parent
354c35220d
commit
547d26aa08
9 changed files with 146 additions and 25 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1201,6 +1201,22 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
PyThreadState_EnterTracing(PyThreadState *tstate)
|
||||
{
|
||||
tstate->tracing++;
|
||||
_PyThreadState_DisableTracing(tstate);
|
||||
}
|
||||
|
||||
void
|
||||
PyThreadState_LeaveTracing(PyThreadState *tstate)
|
||||
{
|
||||
tstate->tracing--;
|
||||
_PyThreadState_ResetTracing(tstate);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Routines for advanced debuggers, requested by David Beazley.
|
||||
Don't use unless you know what you are doing! */
|
||||
|
||||
|
|
|
@ -256,8 +256,7 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
|
|||
}
|
||||
|
||||
/* Disallow tracing in hooks unless explicitly enabled */
|
||||
ts->tracing++;
|
||||
ts->cframe->use_tracing = 0;
|
||||
PyThreadState_EnterTracing(ts);
|
||||
while ((hook = PyIter_Next(hooks)) != NULL) {
|
||||
_Py_IDENTIFIER(__cantrace__);
|
||||
PyObject *o;
|
||||
|
@ -270,14 +269,12 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
|
|||
break;
|
||||
}
|
||||
if (canTrace) {
|
||||
ts->cframe->use_tracing = (ts->c_tracefunc || ts->c_profilefunc) ? 255 : 0;
|
||||
ts->tracing--;
|
||||
PyThreadState_LeaveTracing(ts);
|
||||
}
|
||||
PyObject* args[2] = {eventName, eventArgs};
|
||||
o = _PyObject_FastCallTstate(ts, hook, args, 2);
|
||||
if (canTrace) {
|
||||
ts->tracing++;
|
||||
ts->cframe->use_tracing = 0;
|
||||
PyThreadState_EnterTracing(ts);
|
||||
}
|
||||
if (!o) {
|
||||
break;
|
||||
|
@ -285,8 +282,7 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
|
|||
Py_DECREF(o);
|
||||
Py_CLEAR(hook);
|
||||
}
|
||||
ts->cframe->use_tracing = (ts->c_tracefunc || ts->c_profilefunc) ? 255 : 0;
|
||||
ts->tracing--;
|
||||
PyThreadState_LeaveTracing(ts);
|
||||
if (_PyErr_Occurred(ts)) {
|
||||
goto exit;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue