diff options
author | Kristján Valur Jónsson <sweskman@gmail.com> | 2022-08-23 11:23:39 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-23 11:23:39 (GMT) |
commit | d23ab79952836e67216113d9195c9c0e879b3e83 (patch) | |
tree | a4d6b2dd666c1a0e16dd0c409abfb35e86ed158d /Objects | |
parent | 9c34d644edec7e5d4da78317ad2bbceb246aa039 (diff) | |
download | cpython-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.c | 13 |
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. */ |