From b0d6bf2a34d5e2e0cfb2410f58e768935d527be0 Mon Sep 17 00:00:00 2001 From: Ben Gamari <ben@smart-cactus.org> Date: Tue, 18 Jun 2019 12:07:50 -0400 Subject: [PATCH] rts: Reset STATIC_LINK field of reverted CAFs When we revert a CAF we must reset the STATIC_LINK field lest the GC might ignore the CAF (e.g. as it carries the STATIC_FLAG_LIST flag) and will consequently overlook references to object code that we are trying to unload. This would result in the reachable object code being unloaded. See Note [CAF lists] and Note [STATIC_LINK fields]. This fixes #16842. Idea-due-to: Phuong Trinh <lolotp@fb.com> --- rts/sm/GCAux.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/rts/sm/GCAux.c b/rts/sm/GCAux.c index 23ed3f0622f7..e8ca0c4002a0 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; } -- GitLab