Skip to content

Commit

Permalink
Fix interpreter crash caused by RUBY_INTERNAL_EVENT_NEWOBJ + Ractors
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
KJTsanaktsidis authored and byroot committed Mar 9, 2023
1 parent 1a0d3ec commit 7bd7aee
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
1 change: 1 addition & 0 deletions gc.c
Expand Up @@ -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);
Expand Down
17 changes: 17 additions & 0 deletions 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

0 comments on commit 7bd7aee

Please sign in to comment.