Hi list,
On page 284 of Pickaxe, 2nd edition there is a passage:
If you create a Ruby object from C and store it in a C global variable without exporting it to Ruby, you must at least tell the garbage collector about it, lest ye be reaped inadvertently.
static VALUE obj;
/* ... */
obj = rb_ary_new();
rb_global_variable(obj);
I would like to reproduce this issue, but don’t know how. As far as I
understand, if rb_global_variable(obj) is not called then once the GC
will try to free up garbage memory it will try to destroy obj. GC will
fail and something interesting should happen
I tried to implement this bug. While writing this e-mail I started to
think that I misunderstood what Dave T. is stating and that I’m
going the wrong way. But here is my code, in case I’m doing something
right:
reg_global.c:
1 #include <ruby.h>
2
3 static VALUE str;
4
5 int
6 main(int argc, char *argv)
7 {
8 ruby_init();
9 ruby_init_loadpath();
10
11 / Create a string variable end export it to ruby */
12 str = rb_str_new2(“FooBar”);
13 rb_define_variable("$value", &str);
14
15 rb_require(“reg_global.rb”);
16
17 ruby_finalize();
18 return 0;
19 }
reg_global.rb:
1 # this script should be called from embedded ruby interpreter
2
3 def wrapper
4 p “value: #{$value}, id: #{$value.object_id}”
5 ObjectSpace.define_finalizer($value, lambda { |id| p “Finalizing
#{id}” })
6 $value = nil
7 end
8
9 wrapper
10
11 ObjectSpace.garbage_collect
When I execute reg_global I see the following (nothing special):
“value: FooBar, id: 76750”
“Finalizing 76750”
I expected Ruby to crash after this line:
11 ObjectSpace.garbage_collect
Has anyone some hints on how to reproduce the bug described in paragraph
above ?