@@ -278,18 +278,23 @@ frame_disable_deferred_refcounting(_PyInterpreterFrameCore *frame)
278278 frame -> owner & FRAME_OWNED_BY_GENERATOR );
279279
280280 frame -> f_executable = PyStackRef_AsStrongReference (frame -> f_executable );
281+ if (_PyFrame_IsExternalFrame (frame )) {
282+ return ;
283+ }
284+
285+ _PyInterpreterFrame * f = _PyFrame_Full (frame );
281286
282287 if (frame -> owner & FRAME_OWNED_BY_GENERATOR ) {
283- PyGenObject * gen = _PyGen_GetGeneratorFromFrame (frame );
288+ PyGenObject * gen = _PyGen_GetGeneratorFromFrame (f );
284289 if (gen -> gi_frame_state == FRAME_CLEARED ) {
285290 // gh-124068: if the generator is cleared, then most fields other
286291 // than f_executable are not valid.
287292 return ;
288293 }
289294 }
290295
291- frame -> f_funcobj = PyStackRef_AsStrongReference (frame -> f_funcobj );
292- for (_PyStackRef * ref = frame -> localsplus ; ref < frame -> stackpointer ; ref ++ ) {
296+ f -> f_funcobj = PyStackRef_AsStrongReference (f -> f_funcobj );
297+ for (_PyStackRef * ref = f -> localsplus ; ref < f -> stackpointer ; ref ++ ) {
293298 if (!PyStackRef_IsNullOrInt (* ref ) && !PyStackRef_RefcountOnObject (* ref )) {
294299 * ref = PyStackRef_AsStrongReference (* ref );
295300 }
@@ -315,10 +320,10 @@ disable_deferred_refcounting(PyObject *op)
315320 // use strong references, in case the generator or frame object is
316321 // resurrected by a finalizer.
317322 if (PyGen_CheckExact (op ) || PyCoro_CheckExact (op ) || PyAsyncGen_CheckExact (op )) {
318- frame_disable_deferred_refcounting (& ((PyGenObject * )op )-> gi_iframe );
323+ frame_disable_deferred_refcounting (_PyFrame_Core ( & ((PyGenObject * )op )-> gi_iframe ) );
319324 }
320325 else if (PyFrame_Check (op )) {
321- frame_disable_deferred_refcounting ((( PyFrameObject * )op )-> f_frame );
326+ frame_disable_deferred_refcounting (_PyFrame_Core ((( PyFrameObject * )op )-> f_frame ) );
322327 }
323328}
324329
@@ -478,11 +483,12 @@ gc_visit_thread_stacks(PyInterpreterState *interp, struct collection_state *stat
478483 }
479484
480485 for (_PyInterpreterFrameCore * f = p -> current_frame ; f != NULL ; f = f -> previous ) {
481- if (f -> owner >= FRAME_OWNED_BY_INTERPRETER ) {
486+ if (f -> owner >= FRAME_OWNED_BY_INTERPRETER || _PyFrame_IsExternalFrame ( f ) ) {
482487 continue ;
483488 }
484489
485- _PyStackRef * top = f -> stackpointer ;
490+ _PyInterpreterFrame * frame = _PyFrame_Full (f );
491+ _PyStackRef * top = frame -> stackpointer ;
486492 if (top == NULL ) {
487493 // GH-129236: The stackpointer may be NULL in cases where
488494 // the GC is run during a PyStackRef_CLOSE() call. Skip this
@@ -492,7 +498,7 @@ gc_visit_thread_stacks(PyInterpreterState *interp, struct collection_state *stat
492498 }
493499
494500 gc_visit_stackref (f -> f_executable );
495- while (top != f -> localsplus ) {
501+ while (top != frame -> localsplus ) {
496502 -- top ;
497503 gc_visit_stackref (* top );
498504 }
@@ -875,23 +881,24 @@ gc_visit_thread_stacks_mark_alive(PyInterpreterState *interp, gc_mark_args_t *ar
875881 int err = 0 ;
876882 _Py_FOR_EACH_TSTATE_BEGIN (interp , p ) {
877883 for (_PyInterpreterFrameCore * f = p -> current_frame ; f != NULL ; f = f -> previous ) {
878- if (f -> owner >= FRAME_OWNED_BY_INTERPRETER ) {
884+ if (f -> owner >= FRAME_OWNED_BY_INTERPRETER || _PyFrame_IsExternalFrame ( f ) ) {
879885 continue ;
880886 }
881887
882- if (f -> stackpointer == NULL ) {
888+ _PyInterpreterFrame * frame = _PyFrame_Full (f );
889+ if (frame -> stackpointer == NULL ) {
883890 // GH-129236: The stackpointer may be NULL in cases where
884891 // the GC is run during a PyStackRef_CLOSE() call. Skip this
885892 // frame for now.
886893 continue ;
887894 }
888895
889- _PyStackRef * top = f -> stackpointer ;
896+ _PyStackRef * top = frame -> stackpointer ;
890897 if (gc_visit_stackref_mark_alive (args , f -> f_executable ) < 0 ) {
891898 err = -1 ;
892899 goto exit ;
893900 }
894- while (top != f -> localsplus ) {
901+ while (top != frame -> localsplus ) {
895902 -- top ;
896903 if (gc_visit_stackref_mark_alive (args , * top ) < 0 ) {
897904 err = -1 ;
0 commit comments