bpo-40429: PyThreadState_GetFrame() returns a strong ref (GH-19781)
The PyThreadState_GetFrame() function now returns a strong reference to the frame.
This commit is contained in:
parent
37af21b667
commit
4386b9045e
|
@ -1074,10 +1074,10 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
|
||||||
|
|
||||||
.. c:function:: PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate)
|
.. c:function:: PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate)
|
||||||
|
|
||||||
Get a borrowed reference to the current frame of the Python thread state
|
Get the current frame of the Python thread state *tstate*.
|
||||||
*tstate*.
|
|
||||||
|
|
||||||
Return ``NULL`` if no frame is currently executing.
|
Return a strong reference. Return ``NULL`` if no frame is currently
|
||||||
|
executing.
|
||||||
|
|
||||||
See also :c:func:`PyEval_GetFrame`.
|
See also :c:func:`PyEval_GetFrame`.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
The :c:func:`PyThreadState_GetFrame` function now returns a strong reference
|
||||||
|
to the frame.
|
|
@ -425,10 +425,7 @@ traceback_hash(traceback_t *traceback)
|
||||||
static void
|
static void
|
||||||
traceback_get_frames(traceback_t *traceback)
|
traceback_get_frames(traceback_t *traceback)
|
||||||
{
|
{
|
||||||
PyThreadState *tstate;
|
PyThreadState *tstate = PyGILState_GetThisThreadState();
|
||||||
PyFrameObject *pyframe;
|
|
||||||
|
|
||||||
tstate = PyGILState_GetThisThreadState();
|
|
||||||
if (tstate == NULL) {
|
if (tstate == NULL) {
|
||||||
#ifdef TRACE_DEBUG
|
#ifdef TRACE_DEBUG
|
||||||
tracemalloc_error("failed to get the current thread state");
|
tracemalloc_error("failed to get the current thread state");
|
||||||
|
@ -436,7 +433,8 @@ traceback_get_frames(traceback_t *traceback)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pyframe = PyThreadState_GetFrame(tstate);
|
PyFrameObject *pyframe = PyThreadState_GetFrame(tstate);
|
||||||
|
Py_XDECREF(pyframe); // use a borrowed reference
|
||||||
for (; pyframe != NULL; pyframe = pyframe->f_back) {
|
for (; pyframe != NULL; pyframe = pyframe->f_back) {
|
||||||
if (traceback->nframe < _Py_tracemalloc_config.max_nframe) {
|
if (traceback->nframe < _Py_tracemalloc_config.max_nframe) {
|
||||||
tracemalloc_get_frame(pyframe, &traceback->frames[traceback->nframe]);
|
tracemalloc_get_frame(pyframe, &traceback->frames[traceback->nframe]);
|
||||||
|
|
|
@ -1840,14 +1840,17 @@ _is_running(PyInterpreterState *interp)
|
||||||
"interpreter has more than one thread");
|
"interpreter has more than one thread");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(!PyErr_Occurred());
|
||||||
PyFrameObject *frame = PyThreadState_GetFrame(tstate);
|
PyFrameObject *frame = PyThreadState_GetFrame(tstate);
|
||||||
if (frame == NULL) {
|
if (frame == NULL) {
|
||||||
if (PyErr_Occurred() != NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return (int)(frame->f_executing);
|
|
||||||
|
int executing = (int)(frame->f_executing);
|
||||||
|
Py_DECREF(frame);
|
||||||
|
|
||||||
|
return executing;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -8108,15 +8108,16 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
/* Call super(), without args -- fill in from __class__
|
/* Call super(), without args -- fill in from __class__
|
||||||
and first local variable on the stack. */
|
and first local variable on the stack. */
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
PyFrameObject *f = PyThreadState_GetFrame(tstate);
|
PyFrameObject *frame = PyThreadState_GetFrame(tstate);
|
||||||
if (f == NULL) {
|
if (frame == NULL) {
|
||||||
PyErr_SetString(PyExc_RuntimeError,
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
"super(): no current frame");
|
"super(): no current frame");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyCodeObject *code = PyFrame_GetCode(f);
|
PyCodeObject *code = PyFrame_GetCode(frame);
|
||||||
int res = super_init_without_args(f, code, &type, &obj);
|
int res = super_init_without_args(frame, code, &type, &obj);
|
||||||
|
Py_DECREF(frame);
|
||||||
Py_DECREF(code);
|
Py_DECREF(code);
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
|
|
@ -1372,7 +1372,7 @@ _PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exc_tb == NULL) {
|
if (exc_tb == NULL) {
|
||||||
struct _frame *frame = tstate->frame;
|
PyFrameObject *frame = tstate->frame;
|
||||||
if (frame != NULL) {
|
if (frame != NULL) {
|
||||||
exc_tb = _PyTraceBack_FromFrame(NULL, frame);
|
exc_tb = _PyTraceBack_FromFrame(NULL, frame);
|
||||||
if (exc_tb == NULL) {
|
if (exc_tb == NULL) {
|
||||||
|
|
|
@ -1042,11 +1042,13 @@ PyThreadState_GetInterpreter(PyThreadState *tstate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct _frame*
|
PyFrameObject*
|
||||||
PyThreadState_GetFrame(PyThreadState *tstate)
|
PyThreadState_GetFrame(PyThreadState *tstate)
|
||||||
{
|
{
|
||||||
assert(tstate != NULL);
|
assert(tstate != NULL);
|
||||||
return tstate->frame;
|
PyFrameObject *frame = tstate->frame;
|
||||||
|
Py_XINCREF(frame);
|
||||||
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1165,7 +1167,7 @@ _PyThread_CurrentFrames(void)
|
||||||
for (i = runtime->interpreters.head; i != NULL; i = i->next) {
|
for (i = runtime->interpreters.head; i != NULL; i = i->next) {
|
||||||
PyThreadState *t;
|
PyThreadState *t;
|
||||||
for (t = i->tstate_head; t != NULL; t = t->next) {
|
for (t = i->tstate_head; t != NULL; t = t->next) {
|
||||||
struct _frame *frame = t->frame;
|
PyFrameObject *frame = t->frame;
|
||||||
if (frame == NULL) {
|
if (frame == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue