@@ -471,14 +471,14 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
471471 return gen_send_ex (gen , Py_None , 1 , 0 );
472472 goto throw_here ;
473473 }
474+ PyThreadState * tstate = _PyThreadState_GET ();
475+ assert (tstate != NULL );
474476 if (PyGen_CheckExact (yf ) || PyCoro_CheckExact (yf )) {
475477 /* `yf` is a generator or a coroutine. */
476- PyThreadState * tstate = _PyThreadState_GET ();
477- /* Since we are fast-tracking things by skipping the eval loop,
478- we need to update the current frame so the stack trace
479- will be reported correctly to the user. */
480- /* XXX We should probably be updating the current frame
481- somewhere in ceval.c. */
478+
479+ /* Link frame into the stack to enable complete backtraces. */
480+ /* XXX We should probably be updating the current frame somewhere in
481+ ceval.c. */
482482 _PyInterpreterFrame * prev = tstate -> current_frame ;
483483 frame -> previous = prev ;
484484 tstate -> current_frame = frame ;
@@ -502,10 +502,16 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
502502 Py_DECREF (yf );
503503 goto throw_here ;
504504 }
505+
506+ _PyInterpreterFrame * prev = tstate -> current_frame ;
507+ frame -> previous = prev ;
508+ tstate -> current_frame = frame ;
505509 PyFrameState state = gen -> gi_frame_state ;
506510 gen -> gi_frame_state = FRAME_EXECUTING ;
507511 ret = PyObject_CallFunctionObjArgs (meth , typ , val , tb , NULL );
508512 gen -> gi_frame_state = state ;
513+ tstate -> current_frame = prev ;
514+ frame -> previous = NULL ;
509515 Py_DECREF (meth );
510516 }
511517 Py_DECREF (yf );
0 commit comments