From: "ivoanjo (Ivo Anjo) via ruby-core" Date: 2025-12-03T09:17:39+00:00 Subject: [ruby-core:123998] [Ruby Bug#21710] Segfault when reading object_id after it is set inside RUBY_INTERNAL_EVENT_NEWOBJ Issue #21710 has been updated by ivoanjo (Ivo Anjo). Having `MOVEDOBJ` would be very useful for being able to use the address as identity + I think it may come in handy for caches -- I think it would solve the "a) Be able to identify or reference object without preventing its GC, even if the object is moved". But I'm not sure it solves the whole puzzle, since we'd still need to query/be notified when such "home-grown weak referenced" object is collected. That's where `rb_gc_mark_weak` would indeed be a nice solution, but TBH having: * a "is this ref a valid object"? * or something closer to Java's [Reference Queues](https://docs.oracle.com/en/java/javase/25/docs/api//java.base/java/lang/ref/ReferenceQueue.html) where Ruby would throw the addresses of the objects it GC in an array that could be post-processed later * be able to somehow mark or tell Ruby which objects we want to know about in `FREEOBJ` (possibly even `MOVEDOBJ`) would be enough for the use-case. ---------------------------------------- Bug #21710: Segfault when reading object_id after it is set inside RUBY_INTERNAL_EVENT_NEWOBJ https://bugs.ruby-lang.org/issues/21710#change-115425 * Author: ivoanjo (Ivo Anjo) * Status: Closed * Target version: 4.0 * ruby -v: ruby 4.0.0dev (2025-11-24T08:44:28Z master aeb7689e69) +PRISM [x86_64-linux] * Backport: 3.2: DONTNEED, 3.3: DONTNEED, 3.4: DONTNEED ---------------------------------------- Hey ����. I caught a following segfault when running the [Datadog Ruby Profiler](https://github.com/datadog/dd-trace-rb) test suite on 4.0.0-preview2. The Datadog Ruby Profiler still uses object_ids in `RUBY_INTERNAL_EVENT_NEWOBJ` to simulate weak references. (We know this is deprecated and we plan to move to [`rb_gc_mark_weak`](https://bugs.ruby-lang.org/issues/19783) in the future). I was able to reproduce this bug with both 4.0.0-preview2 as well as a ruby-head build from 2025-11-24. Here's a [very simple reproducer](https://github.com/ivoanjo/lowlevel-toolkit/pull/1): ```c static void on_newobj_event(VALUE tpval, void *data) { VALUE obj = rb_tracearg_object(rb_tracearg_from_tracepoint(tpval)); if (!rb_objspace_internal_object_p(obj)) rb_obj_id(obj); } static VALUE add_object_id(RB_UNUSED_VAR(VALUE _)) { VALUE tp = rb_tracepoint_new(0, RUBY_INTERNAL_EVENT_NEWOBJ, on_newobj_event, NULL); rb_tracepoint_enable(tp); rb_yield(Qnil); rb_tracepoint_disable(tp); return Qnil; } ``` ```ruby puts RUBY_DESCRIPTION require "lowlevel-toolkit" foo = Struct.new(:foo) bar = nil LowlevelToolkit.add_object_id { bar = foo.new(1) } bar.object_id ``` and here's the segfault: ``` examples/add_object_id.rb:8: [BUG] Segmentation fault at 0x0000000000000000 ruby 4.0.0dev (2025-11-24T08:44:28Z master aeb7689e69) +PRISM [x86_64-linux] -- Control frame information ----------------------------------------------- c:0003 p:---- s:0012 e:000011 l:y b:---- CFUNC :object_id c:0002 p:0044 s:0008 E:002170 l:n b:---- EVAL examples/add_object_id.rb:8 [FINISH] c:0001 p:0000 s:0003 E:001dc0 l:y b:---- DUMMY [FINISH] -- Ruby level backtrace information ---------------------------------------- examples/add_object_id.rb:8:in '
' examples/add_object_id.rb:8:in 'object_id' -- Threading information --------------------------------------------------- Total ractor count: 1 Ruby thread count for this ractor: 1 -- Machine register context ------------------------------------------------ RIP: 0x000079c33b33e2cd RBP: 0x00007ffdcee65d10 RSP: 0x00007ffdcee65cd0 RAX: 0x0000000000000000 RBX: 0x000079c33a4ff058 RCX: 0x000079c339000000 RDX: 0x0000000000000000 RDI: 0x0000000000000000 RSI: 0x00000000000fe000 R8: 0x000079c33b35c078 R9: 0x000079c31f2814d0 R10: 0x000058e4893a6ee0 R11: 0xb84a1fbe2b4aab11 R12: 0x0000000000000002 R13: 0x0000000000000000 R14: 0x000058e489384b60 R15: 0x000079c33a5fefa0 EFL: 0x0000000000010246 -- C level backtrace information ------------------------------------------- .rvm/rubies/ruby-head/lib/libruby.so.4.0(rb_print_backtrace+0x24) [0x79c33b392149] .rvm/src/ruby-head/vm_dump.c:1105 .rvm/rubies/ruby-head/lib/libruby.so.4.0(rb_vm_bugreport+0x33f) [0x79c33b39291b] .rvm/src/ruby-head/vm_dump.c:1450 .rvm/rubies/ruby-head/lib/libruby.so.4.0(rb_bug_for_fatal_signal+0x147) [0x79c33b13a3e2] .rvm/rubies/ruby-head/lib/libruby.so.4.0(sigsegv+0x84) [0x79c33b2bea4d] .rvm/src/ruby-head/signal.c:948 .rvm/rubies/ruby-head/lib/libruby.so.4.0(sigill) (null):0 /lib/x86_64-linux-gnu/libc.so.6(0x79c33ac45330) [0x79c33ac45330] .rvm/rubies/ruby-head/lib/libruby.so.4.0(rb_obj_field_get+0x105) [0x79c33b33e2cd] .rvm/src/ruby-head/variable.c:1412 .rvm/rubies/ruby-head/lib/libruby.so.4.0(object_id_get+0x4e) [0x79c33b16ed28] .rvm/src/ruby-head/gc.c:1875 .rvm/rubies/ruby-head/lib/libruby.so.4.0(object_id0+0x46) [0x79c33b16ed78] .rvm/src/ruby-head/gc.c:1895 .rvm/rubies/ruby-head/lib/libruby.so.4.0(object_id+0xb1) [0x79c33b16ee93] .rvm/src/ruby-head/gc.c:1936 .rvm/rubies/ruby-head/lib/libruby.so.4.0(rb_find_object_id+0x43) [0x79c33b16f6ea] .rvm/src/ruby-head/gc.c:2179 .rvm/rubies/ruby-head/lib/libruby.so.4.0(rb_obj_id+0x2e) [0x79c33b16f75a] .rvm/src/ruby-head/gc.c:2234 .rvm/rubies/ruby-head/lib/libruby.so.4.0(ractor_safe_call_cfunc_0+0x30) [0x79c33b35c0a8] .rvm/src/ruby-head/vm_insnhelper.c:3718 .rvm/rubies/ruby-head/lib/libruby.so.4.0(vm_call_cfunc_with_frame_+0x221) [0x79c33b35ccb1] .rvm/src/ruby-head/vm_insnhelper.c:3902 .rvm/rubies/ruby-head/lib/libruby.so.4.0(vm_call_cfunc_with_frame+0x76) [0x79c33b35cf26] .rvm/src/ruby-head/vm_insnhelper.c:3948 .rvm/rubies/ruby-head/lib/libruby.so.4.0(vm_call_cfunc_other+0x12b) [0x79c33b35d053] .rvm/src/ruby-head/vm_insnhelper.c:3974 .rvm/rubies/ruby-head/lib/libruby.so.4.0(vm_call_cfunc+0x147) [0x79c33b35d49a] .rvm/src/ruby-head/vm_insnhelper.c:4056 .rvm/rubies/ruby-head/lib/libruby.so.4.0(vm_call_method_each_type+0x180) [0x79c33b360161] .rvm/src/ruby-head/vm_insnhelper.c:4888 .rvm/rubies/ruby-head/lib/libruby.so.4.0(vm_call_method+0xa1) [0x79c33b360c1d] .rvm/src/ruby-head/vm_insnhelper.c:5014 .rvm/rubies/ruby-head/lib/libruby.so.4.0(vm_call_general+0x2f) [0x79c33b360e1f] .rvm/src/ruby-head/vm_insnhelper.c:5058 .rvm/rubies/ruby-head/lib/libruby.so.4.0(vm_sendish+0x1d3) [0x79c33b363689] .rvm/src/ruby-head/vm_insnhelper.c:6124 .rvm/rubies/ruby-head/lib/libruby.so.4.0(vm_exec_core+0x3b1d) [0x79c33b36b42c] .rvm/src/ruby-head/insns.def:903 .rvm/rubies/ruby-head/lib/libruby.so.4.0(rb_vm_exec+0x140) [0x79c33b384d94] .rvm/src/ruby-head/vm.c:2784 .rvm/rubies/ruby-head/lib/libruby.so.4.0(rb_iseq_eval_main+0x3d) [0x79c33b385be2] .rvm/src/ruby-head/vm.c:3050 .rvm/rubies/ruby-head/lib/libruby.so.4.0(rb_ec_exec_node+0x128) [0x79c33b145eb4] .rvm/src/ruby-head/eval.c:283 .rvm/rubies/ruby-head/lib/libruby.so.4.0(ruby_run_node+0x8a) [0x79c33b146025] .rvm/src/ruby-head/eval.c:321 .rvm/rubies/ruby-head/bin/ruby(rb_main+0x4c) [0x58e47500e51e] ./main.c:42 .rvm/rubies/ruby-head/bin/ruby(main+0x62) [0x58e47500e596] ./main.c:62 ``` Let me know if I can provide any more info! ---Files-------------------------------- bug-21710.patch (1.25 KB) -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/