From f4476f0d07c781c906ed1353d8e1be5a7314d6e7 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Fri, 20 Dec 2024 16:48:48 -0500 Subject: [PATCH] Disable GC during RUBY_INTERNAL_EVENT_NEWOBJ We must disable GC when running RUBY_INTERNAL_EVENT_NEWOBJ hooks because the callback could call xmalloc which could potentially trigger a GC, and a lot of code is unsafe to trigger a GC right after an object has been allocated because they perform initialization for the object and assume that the GC does not trigger before then. --- gc.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gc.c b/gc.c index 67857ed44c..1ec159a2da 100644 --- a/gc.c +++ b/gc.c @@ -1031,7 +1031,16 @@ newobj_of(rb_ractor_t *cr, VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v { memset((char *)obj + RVALUE_SIZE, 0, rb_gc_obj_slot_size(obj) - RVALUE_SIZE); - rb_gc_event_hook(obj, RUBY_INTERNAL_EVENT_NEWOBJ); + /* We must disable GC here because the callback could call xmalloc + * which could potentially trigger a GC, and a lot of code is unsafe + * to trigger a GC right after an object has been allocated because + * they perform initialization for the object and assume that the + * GC does not trigger before then. */ + bool gc_disabled = RTEST(rb_gc_disable_no_rest()); + { + rb_gc_event_hook(obj, RUBY_INTERNAL_EVENT_NEWOBJ); + } + if (!gc_disabled) rb_gc_enable(); } RB_VM_LOCK_LEAVE_CR_LEV(cr, &lev); }