[#99115] [Ruby master Bug#17023] How to prevent String memory to be relocated in ruby-ffi — larskanis@...
Issue #17023 has been reported by larskanis (Lars Kanis).
22 messages
2020/07/10
[#99375] [Ruby master Feature#17055] Allow suppressing uninitialized instance variable and method redefined verbose mode warnings — merch-redmine@...
Issue #17055 has been reported by jeremyevans0 (Jeremy Evans).
29 messages
2020/07/28
[#101207] [Ruby master Feature#17055] Allow suppressing uninitialized instance variable and method redefined verbose mode warnings
— merch-redmine@...
2020/12/02
Issue #17055 has been updated by jeremyevans0 (Jeremy Evans).
[#101231] Re: [Ruby master Feature#17055] Allow suppressing uninitialized instance variable and method redefined verbose mode warnings
— Austin Ziegler <halostatue@...>
2020/12/03
What does this mean?
[ruby-core:99120] [Ruby master Bug#17023] How to prevent String memory to be relocated in ruby-ffi
From:
duerst@...
Date:
2020-07-11 00:24:57 UTC
List:
ruby-core #99120
Issue #17023 has been updated by duerst (Martin D=FCrst).
Assignee set to tenderlovemaking (Aaron Patterson)
Status changed from Open to Assigned
----------------------------------------
Bug #17023: How to prevent String memory to be relocated in ruby-ffi
https://bugs.ruby-lang.org/issues/17023#change-86496
* Author: larskanis (Lars Kanis)
* Status: Assigned
* Priority: Normal
* Assignee: tenderlovemaking (Aaron Patterson)
* ruby -v: ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN
----------------------------------------
[ruby-ffi](https://github.com/ffi/ffi) allows to pass String objects to C b=
y using the `:string` argument type. This way the string memory returned by=
`RSTRING_PTR` is passed to the C function. The user has to ensure on Ruby =
level that the string isn't GC'ed - as long as it is used on C level. That'=
s the contract and this worked with all past ruby versions, but ruby-2.7 in=
troduced `GC.compact`, which can relocate strings to another memory locatio=
n.
This example shows the situation and that the string is relocated although =
it is still referenced in ruby code:
```ruby
File.write "string-relocate.c", <<-EOC
static char *g_str;
void set(char* str) {
g_str =3D str;
}
char* get() {
return g_str;
}
EOC
system "gcc -shared -fPIC string-relocate.c -o string-relocate.so"
require 'ffi'
class Foo
extend FFI::Library
ffi_lib File.expand_path('string-relocate.so')
attach_function :set, [:string], :void
attach_function :get, [], :string
def initialize(count)
proc {} # necessary to trigger relocation
a =3D "a" * count
set(a)
GC.verify_compaction_references(toward: :empty, double_heap: true)
puts "get(#{count}): #{get} (should be: #{a})"
end
end
Foo.new(23)
Foo.new(24)
```
The output looks like so on ruby-2.7.1:
```
get(23): (should be: aaaaaaaaaaaaaaaaaaaaaaa)
get(24): aaaaaaaaaaaaaaaaaaaaaaaa (should be: aaaaaaaaaaaaaaaaaaaaaaaa)
```
So using `GC.compact` while a string parameter is in use, both on Ruby and =
on C level, can cause invalid memory access. How can this prevented?
A C extension is expected to use `rb_gc_mark()` in order to pin the VALUE t=
o a memory location. But I couldn't find a way to pin a `VALUE` at the time=
the argument is passed to the C function, which is the only point in time =
ruby-ffi has access to it.
---Files--------------------------------
string-relocate.rb (653 Bytes)
-- =
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:[email protected]?subject=3Dunsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>