diff --git a/rts/sm/GCAux.c b/rts/sm/GCAux.c index 23ed3f0622f77ea3060d637c1cbbf06ed5bc6851..e8ca0c4002a0dc8aec615e20637d7bfda2972307 100644 --- a/rts/sm/GCAux.c +++ b/rts/sm/GCAux.c @@ -114,16 +114,21 @@ isAlive(StgClosure *p) void revertCAFs( void ) { - StgIndStatic *c; + StgIndStatic *c = revertible_caf_list; - for (c = revertible_caf_list; - c != (StgIndStatic *)END_OF_CAF_LIST; - c = (StgIndStatic *)c->static_link) - { + while (c != (StgIndStatic *) END_OF_CAF_LIST) { c = (StgIndStatic *)UNTAG_STATIC_LIST_PTR(c); + StgIndStatic *next = (StgIndStatic *) c->static_link; + SET_INFO((StgClosure *)c, c->saved_info); c->saved_info = NULL; - // could, but not necessary: c->static_link = NULL; + // We must reset static_link lest the major GC finds that + // static_flag==3 and will consequently ignore references + // into code that we are trying to unload. This would result + // in reachable object code being unloaded prematurely. + // See #16842. + c->static_link = NULL; + c = next; } revertible_caf_list = (StgIndStatic*)END_OF_CAF_LIST; }