diff options
author | Pablo Galindo Salgado <Pablogsal@gmail.com> | 2022-07-05 18:18:47 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-05 18:18:47 (GMT) |
commit | 40d81fd63b46cf998880ce3bf3e5cb42bc3199c1 (patch) | |
tree | 16784196332e1bdd8a4a94984e4ec516ba0a1e67 /Python/ceval.c | |
parent | 5f319308a820f49fec66fc3ade50bbaa9fe2105d (diff) | |
download | cpython-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.c | 26 |
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; } |