From 7bd7aee02e303de27d2cddfc5ef47e612d6782cb Mon Sep 17 00:00:00 2001 From: KJ Tsanaktsidis Date: Sat, 8 Jan 2022 15:21:46 +1100 Subject: [PATCH] Fix interpreter crash caused by RUBY_INTERNAL_EVENT_NEWOBJ + Ractors When a Ractor is created whilst a tracepoint for RUBY_INTERNAL_EVENT_NEWOBJ is active, the interpreter crashes. This is because during the early setup of the Ractor, the stdio objects are created, which allocates Ruby objects, which fires the tracepoint. However, the tracepoint machinery tries to dereference the control frame (ec->cfp->pc), which isn't set up yet and so crashes with a null pointer dereference. Fix this by not firing GC tracepoints if cfp isn't yet set up. --- gc.c | 1 + test/objspace/test_ractor.rb | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 test/objspace/test_ractor.rb diff --git a/gc.c b/gc.c index 31a5788297..b8c8ae099d 100644 --- a/gc.c +++ b/gc.c @@ -2484,6 +2484,7 @@ rb_objspace_set_event_hook(const rb_event_flag_t event) static void gc_event_hook_body(rb_execution_context_t *ec, rb_objspace_t *objspace, const rb_event_flag_t event, VALUE data) { + if (UNLIKELY(!ec->cfp)) return; const VALUE *pc = ec->cfp->pc; if (pc && VM_FRAME_RUBYFRAME_P(ec->cfp)) { int prev_opcode = rb_vm_insn_addr2opcode((void *)*ec->cfp->iseq->body->iseq_encoded); diff --git a/test/objspace/test_ractor.rb b/test/objspace/test_ractor.rb new file mode 100644 index 0000000000..b7008ea731 --- /dev/null +++ b/test/objspace/test_ractor.rb @@ -0,0 +1,17 @@ +require "test/unit" + +class TestObjSpaceRactor < Test::Unit::TestCase + def test_tracing_does_not_crash + assert_ractor(<<~RUBY, require: 'objspace') + ObjectSpace.trace_object_allocations do + r = Ractor.new do + obj = 'a' * 1024 + Ractor.yield obj + end + + r.take + r.take + end + RUBY + end +end