summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorPablo Galindo Salgado <Pablogsal@gmail.com>2022-07-05 18:18:47 (GMT)
committerGitHub <noreply@github.com>2022-07-05 18:18:47 (GMT)
commit40d81fd63b46cf998880ce3bf3e5cb42bc3199c1 (patch)
tree16784196332e1bdd8a4a94984e4ec516ba0a1e67 /Python/ceval.c
parent5f319308a820f49fec66fc3ade50bbaa9fe2105d (diff)
downloadcpython-40d81fd63b46cf998880ce3bf3e5cb42bc3199c1.zip
cpython-40d81fd63b46cf998880ce3bf3e5cb42bc3199c1.tar.gz
cpython-40d81fd63b46cf998880ce3bf3e5cb42bc3199c1.tar.bz2
gh-94510: Raise on re-entrant calls to sys.setprofile and sys.settrace (GH-94511)
Co-authored-by: Ɓukasz Langa <lukasz@langa.pl>
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 4fcdf9b..cdb14d8 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -6973,10 +6973,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;
}
@@ -6994,6 +7004,7 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
/* Flag that tracing or profiling is turned on */
_PyThreadState_UpdateTracingState(tstate);
+ reentrant = 0;
return 0;
}
@@ -7014,10 +7025,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;
}
@@ -7027,15 +7049,15 @@ _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 */
_PyThreadState_UpdateTracingState(tstate);
- Py_XDECREF(traceobj);
-
Py_XINCREF(arg);
+ Py_XDECREF(traceobj);
tstate->c_traceobj = arg;
tstate->c_tracefunc = func;
/* Flag that tracing or profiling is turned on */
_PyThreadState_UpdateTracingState(tstate);
+ reentrant = 0;
return 0;
}