summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorKristján Valur Jónsson <sweskman@gmail.com>2022-08-23 11:23:39 (GMT)
committerGitHub <noreply@github.com>2022-08-23 11:23:39 (GMT)
commitd23ab79952836e67216113d9195c9c0e879b3e83 (patch)
treea4d6b2dd666c1a0e16dd0c409abfb35e86ed158d /Objects
parent9c34d644edec7e5d4da78317ad2bbceb246aa039 (diff)
downloadcpython-d23ab79952836e67216113d9195c9c0e879b3e83.zip
cpython-d23ab79952836e67216113d9195c9c0e879b3e83.tar.gz
cpython-d23ab79952836e67216113d9195c9c0e879b3e83.tar.bz2
[3.10] GH--93592: Fix frame chain when throwing exceptions into coroutines (GH-95207)
Diffstat (limited to 'Objects')
-rw-r--r--Objects/genobject.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 123c17a..4f6fefd 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -439,20 +439,25 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
/* `yf` is a generator or a coroutine. */
PyThreadState *tstate = _PyThreadState_GET();
PyFrameObject *f = tstate->frame;
+ PyFrameObject *gf = gen->gi_frame;
/* Since we are fast-tracking things by skipping the eval loop,
we need to update the current frame so the stack trace
will be reported correctly to the user. */
/* XXX We should probably be updating the current frame
somewhere in ceval.c. */
- tstate->frame = gen->gi_frame;
+ assert(gf->f_back == NULL);
+ Py_XINCREF(f);
+ gf->f_back = f;
+ tstate->frame = gf;
/* Close the generator that we are currently iterating with
'yield from' or awaiting on with 'await'. */
- PyFrameState state = gen->gi_frame->f_state;
- gen->gi_frame->f_state = FRAME_EXECUTING;
+ PyFrameState state = gf->f_state;
+ gf->f_state = FRAME_EXECUTING;
ret = _gen_throw((PyGenObject *)yf, close_on_genexit,
typ, val, tb);
- gen->gi_frame->f_state = state;
+ gf->f_state = state;
+ Py_CLEAR(gf->f_back);
tstate->frame = f;
} else {
/* `yf` is an iterator or a coroutine-like object. */