diff options
author | Victor Stinner <vstinner@python.org> | 2020-03-13 16:39:12 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-13 16:39:12 +0100 |
commit | 309d7cc5df4e2bf3086c49eb2b1b56b929554500 (patch) | |
tree | 18fefb154766c2c568ae128f42b115090f7d05eb /Python/ceval.c | |
parent | 9ee88cde1abf7f274cc55a0571b1c2cdb1263743 (diff) | |
download | cpython-git-309d7cc5df4e2bf3086c49eb2b1b56b929554500.tar.gz |
bpo-35370: Add _PyEval_SetTrace() function (GH-18975)
* sys.settrace(), sys.setprofile() and _lsprof.Profiler.enable() now
properly report PySys_Audit() error if "sys.setprofile" or
"sys.settrace" audit event is denied.
* Add _PyEval_SetProfile() and _PyEval_SetTrace() function: similar
to PyEval_SetProfile() and PyEval_SetTrace() but take a tstate
parameter and return -1 on error.
* Add _PyObject_FastCallTstate() function.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 74 |
1 files changed, 54 insertions, 20 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index ccd1c06a39..fc4f718de2 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4586,51 +4586,85 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, return result; } -void -PyEval_SetProfile(Py_tracefunc func, PyObject *arg) +int +_PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) { + assert(tstate != NULL); + /* The caller must hold the GIL */ + assert(PyGILState_Check()); + + /* Call PySys_Audit() in the context of the current thread state, + even if tstate is not the current thread state. */ if (PySys_Audit("sys.setprofile", NULL) < 0) { - return; + return -1; } - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *temp = tstate->c_profileobj; - Py_XINCREF(arg); + PyObject *profileobj = tstate->c_profileobj; + tstate->c_profilefunc = NULL; tstate->c_profileobj = NULL; - /* Must make sure that tracing is not ignored if 'temp' is freed */ + /* Must make sure that tracing is not ignored if 'profileobj' is freed */ tstate->use_tracing = tstate->c_tracefunc != NULL; - Py_XDECREF(temp); - tstate->c_profilefunc = func; + Py_XDECREF(profileobj); + + Py_XINCREF(arg); tstate->c_profileobj = arg; + tstate->c_profilefunc = func; + /* Flag that tracing or profiling is turned on */ tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL); + return 0; } void -PyEval_SetTrace(Py_tracefunc func, PyObject *arg) +PyEval_SetProfile(Py_tracefunc func, PyObject *arg) +{ + PyThreadState *tstate = _PyThreadState_GET(); + (void)_PyEval_SetProfile(tstate, func, arg); +} + +int +_PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) { + assert(tstate != NULL); + /* The caller must hold the GIL */ + assert(PyGILState_Check()); + + /* Call PySys_Audit() in the context of the current thread state, + even if tstate is not the current thread state. */ if (PySys_Audit("sys.settrace", NULL) < 0) { - return; + return -1; } - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - PyObject *temp = tstate->c_traceobj; - runtime->ceval.tracing_possible += (func != NULL) - (tstate->c_tracefunc != NULL); - Py_XINCREF(arg); + struct _ceval_runtime_state *ceval = &tstate->interp->runtime->ceval; + PyObject *traceobj = tstate->c_traceobj; + ceval->tracing_possible += (func != NULL) - (tstate->c_tracefunc != NULL); + 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; + /* Must make sure that profiling is not ignored if 'traceobj' is freed */ + tstate->use_tracing = (tstate->c_profilefunc != NULL); + Py_XDECREF(traceobj); + + Py_XINCREF(arg); tstate->c_traceobj = arg; + tstate->c_tracefunc = func; + /* Flag that tracing or profiling is turned on */ tstate->use_tracing = ((func != NULL) || (tstate->c_profilefunc != NULL)); + + return 0; +} + +void +PyEval_SetTrace(Py_tracefunc func, PyObject *arg) +{ + PyThreadState *tstate = _PyThreadState_GET(); + (void)_PyEval_SetTrace(tstate, func, arg); } + void _PyEval_SetCoroutineOriginTrackingDepth(PyThreadState *tstate, int new_depth) { |