* [ruby-core:121490] [Ruby Bug#21208] `Ractor#send(move: true)` allow moving objects that are on the stack, and used by C code.
@ 2025-03-31 18:49 byroot (Jean Boussier) via ruby-core
2025-04-01 7:51 ` [ruby-core:121495] " byroot (Jean Boussier) via ruby-core
2025-04-01 20:16 ` [ruby-core:121502] " luke-gru (Luke Gruber) via ruby-core
0 siblings, 2 replies; 3+ messages in thread
From: byroot (Jean Boussier) via ruby-core @ 2025-03-31 18:49 UTC (permalink / raw)
To: ruby-core; +Cc: byroot (Jean Boussier)
Issue #21208 has been reported by byroot (Jean Boussier).
----------------------------------------
Bug #21208: `Ractor#send(move: true)` allow moving objects that are on the stack, and used by C code.
https://bugs.ruby-lang.org/issues/21208
* Author: byroot (Jean Boussier)
* Status: Open
* Assignee: ractor
* Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
The following script causes a crash:
```ruby
rac = Ractor.new do
Ractor.receive
end
hash = Hash[*50.times]
hash.merge!(12 => 0, 14 => 0) do |key, old_val, new_val|
if key == 12
rac.send(hash, move: true)
end
new_val
end
p rac.take
```
Contrary to previous crashes related to `send(move: true)`, I'm afraid this one is with the design of the feature itself, not just the implementation.
If we allow objects to be moved, any C code that calls `rb_yield()` may cause memory corruption if one of the objects it uses is moved.
I personally can't see any realistic solution to this.
--
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/
^ permalink raw reply [flat|nested] 3+ messages in thread
* [ruby-core:121495] [Ruby Bug#21208] `Ractor#send(move: true)` allow moving objects that are on the stack, and used by C code.
2025-03-31 18:49 [ruby-core:121490] [Ruby Bug#21208] `Ractor#send(move: true)` allow moving objects that are on the stack, and used by C code byroot (Jean Boussier) via ruby-core
@ 2025-04-01 7:51 ` byroot (Jean Boussier) via ruby-core
2025-04-01 20:16 ` [ruby-core:121502] " luke-gru (Luke Gruber) via ruby-core
1 sibling, 0 replies; 3+ messages in thread
From: byroot (Jean Boussier) via ruby-core @ 2025-04-01 7:51 UTC (permalink / raw)
To: ruby-core; +Cc: byroot (Jean Boussier)
Issue #21208 has been updated by byroot (Jean Boussier).
> The following script causes a crash
Actually, that was only because I was on an older branch, it no longer crash on `master`, and even behave somewhat correctly by sheer luck.
The general issue remain, `send(obj, move: true)` essentially zero-out the object slot, and none of the C methods that call `rb_yield` expect that, and I don't think we can realistically handle that everywhere in Ruby itself, and certainly not in C extensions.
----------------------------------------
Bug #21208: `Ractor#send(move: true)` allow moving objects that are on the stack, and used by C code.
https://bugs.ruby-lang.org/issues/21208#change-112516
* Author: byroot (Jean Boussier)
* Status: Open
* Assignee: ractor
* Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
The following script causes a crash:
```ruby
rac = Ractor.new do
Ractor.receive
end
hash = Hash[*50.times]
hash.merge!(12 => 0, 14 => 0) do |key, old_val, new_val|
if key == 12
rac.send(hash, move: true)
end
new_val
end
p rac.take
```
Contrary to previous crashes related to `send(move: true)`, I'm afraid this one is with the design of the feature itself, not just the implementation.
If we allow objects to be moved, any C code that calls `rb_yield()` may cause memory corruption if one of the objects it uses is moved.
I personally can't see any realistic solution to this.
--
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/
^ permalink raw reply [flat|nested] 3+ messages in thread
* [ruby-core:121502] [Ruby Bug#21208] `Ractor#send(move: true)` allow moving objects that are on the stack, and used by C code.
2025-03-31 18:49 [ruby-core:121490] [Ruby Bug#21208] `Ractor#send(move: true)` allow moving objects that are on the stack, and used by C code byroot (Jean Boussier) via ruby-core
2025-04-01 7:51 ` [ruby-core:121495] " byroot (Jean Boussier) via ruby-core
@ 2025-04-01 20:16 ` luke-gru (Luke Gruber) via ruby-core
1 sibling, 0 replies; 3+ messages in thread
From: luke-gru (Luke Gruber) via ruby-core @ 2025-04-01 20:16 UTC (permalink / raw)
To: ruby-core; +Cc: luke-gru (Luke Gruber)
Issue #21208 has been updated by luke-gru (Luke Gruber).
Hmm... this is tricky, good find! This probably won't occur often, I'm having a hard time coming up with a situation where it would happen with some benign looking code.
It's fun thinking about solutions to these kinds of things, so as thought experiment if we could somehow disallow `r.send(move: true)` inside blocks called from ruby methods that are implemented in C and that call `rb_yield` and modify `self` with the results of the block, then the issue would go away, right? I don't think `(move: true)` will be used as often as copying the object or just using a shareable object (though I could be wrong) so it's not a deal breaker for ractors in general, but it's a shame.
There could be a way around this I think, if we disallow calling this method with `move: true` in certain scenarios, maybe prohibiting its use from blocks yielded from C (very limiting), or differentiating between mutable and immutable yields, etc. Not that it wouldn't be tricky, but it's not impossible. If a block would be unknown mutability (such as from a C extension), it would be prohibited, etc. I'll have to think more about this, but for now I think letting it exist as a bug and seeing if it rears its head is probably the best "solution".
----------------------------------------
Bug #21208: `Ractor#send(move: true)` allow moving objects that are on the stack, and used by C code.
https://bugs.ruby-lang.org/issues/21208#change-112523
* Author: byroot (Jean Boussier)
* Status: Open
* Assignee: ractor
* Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
The following script causes a crash:
```ruby
rac = Ractor.new do
Ractor.receive
end
hash = Hash[*50.times]
hash.merge!(12 => 0, 14 => 0) do |key, old_val, new_val|
if key == 12
rac.send(hash, move: true)
end
new_val
end
p rac.take
```
Contrary to previous crashes related to `send(move: true)`, I'm afraid this one is with the design of the feature itself, not just the implementation.
If we allow objects to be moved, any C code that calls `rb_yield()` may cause memory corruption if one of the objects it uses is moved.
I personally can't see any realistic solution to this.
--
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/
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-04-01 20:17 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-31 18:49 [ruby-core:121490] [Ruby Bug#21208] `Ractor#send(move: true)` allow moving objects that are on the stack, and used by C code byroot (Jean Boussier) via ruby-core
2025-04-01 7:51 ` [ruby-core:121495] " byroot (Jean Boussier) via ruby-core
2025-04-01 20:16 ` [ruby-core:121502] " luke-gru (Luke Gruber) via ruby-core
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).