Bug #20267
closedHashes that use ar_table aren't moved properly across ractors
Description
This crashes in debug build and gives weird results in non debug build, because the ar_table values aren't copied over to the new "embedded" hash during a move across ractors.
r = Ractor.new {
hash = receive
puts hash
}
obj = {
"1" => 1,
"2" => 2,
"3" => 3,
}
puts obj
r.send(obj, move: true)
r.take
Crash log:
/home/lukeg/workspace/ruby-build/miniruby(sigsegv+0x4d) [0x5641e67d105d] ../ruby/signal.c:926
/lib/x86_64-linux-gnu/libc.so.6(0x7fb4baa42520) [0x7fb4baa42520]
/home/lukeg/workspace/ruby-build/miniruby(RB_BUILTIN_TYPE+0x0) [0x5641e6778db0] ../ruby/ractor.c:3128
/home/lukeg/workspace/ruby-build/miniruby(rbimpl_RB_TYPE_P_fastpath) ../ruby/include/ruby/internal/value_type.h:351
/home/lukeg/workspace/ruby-build/miniruby(RB_TYPE_P) ../ruby/include/ruby/internal/value_type.h:378
/home/lukeg/workspace/ruby-build/miniruby(RB_FL_ABLE) ../ruby/include/ruby/internal/fl_type.h:449
/home/lukeg/workspace/ruby-build/miniruby(RB_FL_TEST_RAW) ../ruby/include/ruby/internal/fl_type.h:471
/home/lukeg/workspace/ruby-build/miniruby(rb_ractor_shareable_p) ../ruby/include/ruby/ractor.h:256
/home/lukeg/workspace/ruby-build/miniruby(reset_belonging_enter) ../ruby/ractor.c:3121
Updated by luke-gru (Luke Gruber) over 1 year ago
I created a patch here: https://github.com/ruby/ruby/pull/9983
Updated by hsbt (Hiroshi SHIBATA) 8 months ago
- Status changed from Open to Assigned
- Assignee set to ko1 (Koichi Sasada)
Updated by byroot (Jean Boussier) 2 months ago
- Status changed from Assigned to Closed
Applied in changeset git|0350290262ea0fbc4e1807901797ee8a6970c2b9.
Ractor: Fix moving embedded objects
[Bug #20271]
[Bug #20267]
[Bug #20255]
rb_obj_alloc(RBASIC_CLASS(obj))
will always allocate from the basic
40B pool, so if obj
is larger than 40B
, we'll create a corrupted
object when we later copy the shape_id.
Instead we can use the same logic than ractor copy, which is
to use rb_obj_clone
, and later ask the GC to free the original
object.
We then must turn it into a T_OBJECT
, because otherwise
just changing its class to RactorMoved
leaves a lot of
ways to keep using the object, e.g.:
a = [1, 2, 3]
Ractor.new{}.send(a, move: true)
[].concat(a) # Should raise, but wasn't.
If it turns out that rb_obj_clone
isn't performant enough
for some uses, we can always have carefully crafted specialized
paths for the types that would benefit from it.
Updated by byroot (Jean Boussier) 23 days ago
- Related to Bug #20165: Ractors moving a Struct breaks beyond the first 3 fields added