From 868d63f0a3a2f63cfc0d5a1a3e6f073722c4fb8e Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Tue, 6 Aug 2024 14:46:19 -0400 Subject: [PATCH] Disable GC even during finalizing We're seeing a crash during shutdown in rb_gc_impl_objspace_free because it's running lazy sweeping during shutdown. It appears that it's due to `finalizing` being set, which causes GC to not be aborted and not disabled which causes it to be in lazy sweeping at shutdown. The full stack trace is: #6 rb_bug (fmt=fmt@entry=0x5643b8ebde78 "lazy sweeping underway when freeing object space") at error.c:1095 #7 0x00005643b8a3c697 in rb_gc_impl_objspace_free (objspace_ptr=) at gc/default.c:9507 #8 0x00005643b8c269eb in ruby_vm_destruct (vm=0x7e2fdc84d000) at vm.c:3141 #9 0x00005643b8a5147b in rb_ec_cleanup (ec=, ex=) at eval.c:263 #10 0x00005643b8a51c93 in ruby_run_node (n=) at eval.c:319 #11 0x00005643b8a4c7c7 in rb_main (argv=0x7fffef15e7f8, argc=18) at ./main.c:43 #12 main (argc=, argv=) at ./main.c:62 --- gc/default.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gc/default.c b/gc/default.c index 1c8305e7c1..c11e5885b0 100644 --- a/gc/default.c +++ b/gc/default.c @@ -3233,11 +3233,17 @@ rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr) #if RGENGC_CHECK_MODE >= 2 gc_verify_internal_consistency(objspace); #endif - if (RUBY_ATOMIC_EXCHANGE(finalizing, 1)) return; /* prohibit incremental GC */ objspace->flags.dont_incremental = 1; + if (RUBY_ATOMIC_EXCHANGE(finalizing, 1)) { + /* Abort incremental marking and lazy sweeping to speed up shutdown. */ + gc_abort(objspace); + dont_gc_on(); + return; + } + /* force to run finalizer */ while (finalizer_table->num_entries) { struct force_finalize_list *list = 0;