[3.10] gh-94510: Raise on re-entrant calls to sys.setprofile and syssettrace (GH-94511) (#94579)

Co-authored-by: Łukasz Langa <lukasz@langa.pl>.
Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
This commit is contained in:
Pablo Galindo Salgado 2022-07-05 19:52:33 +01:00 committed by GitHub
parent fd34bfe484
commit 5e24c80b94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 3 deletions

View file

@ -5525,10 +5525,20 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
/* The caller must hold the GIL */
assert(PyGILState_Check());
static int reentrant = 0;
if (reentrant) {
_PyErr_SetString(tstate, PyExc_RuntimeError, "Cannot install a profile function "
"while another profile function is being installed");
reentrant = 0;
return -1;
}
reentrant = 1;
/* Call _PySys_Audit() in the context of the current thread state,
even if tstate is not the current thread state. */
PyThreadState *current_tstate = _PyThreadState_GET();
if (_PySys_Audit(current_tstate, "sys.setprofile", NULL) < 0) {
reentrant = 0;
return -1;
}
@ -5546,6 +5556,7 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
/* Flag that tracing or profiling is turned on */
tstate->cframe->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL);
reentrant = 0;
return 0;
}
@ -5566,10 +5577,21 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
/* The caller must hold the GIL */
assert(PyGILState_Check());
static int reentrant = 0;
if (reentrant) {
_PyErr_SetString(tstate, PyExc_RuntimeError, "Cannot install a trace function "
"while another trace function is being installed");
reentrant = 0;
return -1;
}
reentrant = 1;
/* Call _PySys_Audit() in the context of the current thread state,
even if tstate is not the current thread state. */
PyThreadState *current_tstate = _PyThreadState_GET();
if (_PySys_Audit(current_tstate, "sys.settrace", NULL) < 0) {
reentrant = 0;
return -1;
}
@ -5579,9 +5601,8 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
tstate->c_traceobj = NULL;
/* Must make sure that profiling is not ignored if 'traceobj' is freed */
tstate->cframe->use_tracing = (tstate->c_profilefunc != NULL);
Py_XDECREF(traceobj);
Py_XINCREF(arg);
Py_XDECREF(traceobj);
tstate->c_traceobj = arg;
tstate->c_tracefunc = func;
@ -5589,6 +5610,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
tstate->cframe->use_tracing = ((func != NULL)
|| (tstate->c_profilefunc != NULL));
reentrant = 0;
return 0;
}