[ruby-core:121504] [Ruby Bug#21210] IO::Buffer gets invalidated on GC compaction
From:
"alanwu (Alan Wu) via ruby-core" <ruby-core@...>
Date:
2025-04-01 23:41:36 UTC
List:
ruby-core #121504
Issue #21210 has been updated by alanwu (Alan Wu).
Another option that maintains validity across movement (untested):
```diff
diff --git a/io_buffer.c b/io_buffer.c
index 0534999319..13102b561d 100644
--- a/io_buffer.c
+++ b/io_buffer.c
@@ -570,7 +570,7 @@ rb_io_buffer_type_for(VALUE klass, VALUE string)
}
else {
// This internally returns the source string if it's already frozen.
- string = rb_str_tmp_frozen_acquire(string);
+ string = rb_str_tmp_frozen_no_embed_acquire(string);
return io_buffer_for_make_instance(klass, string, RB_IO_BUFFER_READONLY);
}
}
```
Looks like the mutable string buffer code paths pin using rb_str_locktmp().
----------------------------------------
Bug #21210: IO::Buffer gets invalidated on GC compaction
https://bugs.ruby-lang.org/issues/21210#change-112525
* Author: hanazuki (Kasumi Hanazuki)
* Status: Open
* ruby -v: ruby 3.5.0dev (2025-04-01T16:11:01Z master 30e5e7c005) +PRISM [x86_64-linux]
* Backport: 3.1: DONTNEED, 3.2: DONTNEED, 3.3: DONTNEED, 3.4: DONTNEED
----------------------------------------
commit:6012145299cfa4ab561360c78710c7f2941a7e9d implemented compaction for `IO::Buffer`.
It looks like this doesn't work well with an `IO::Buffer` that shares memory region with a String object.
I think the problem is that an `IO::Buffer` holds the raw pointer to the String content, and now the content can be moved by GC when the String is embedded.
```ruby
str = +"hello"
buf = IO::Buffer.for(str)
p buf.valid?
GC.verify_compaction_references(expand_heap: true, toward: :empty)
p buf.valid? #=> should be true
```
This example should print two trues. Actually:
```
% ./ruby -v --disable-gems test.rb
ruby 3.5.0dev (2025-04-01T16:11:01Z master 30e5e7c005) +PRISM [x86_64-linux]
true
false
```
--
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/