# How to crash Ruby by not registering global C variable?

**URL:** <https://www.ruby-forum.com/t/how-to-crash-ruby-by-not-registering-global-c-variable/90725>\
**Category:** Ruby\
**Created:** [March 31, 2007, 2:54pm UTC](https://www.ruby-forum.com/t/how-to-crash-ruby-by-not-registering-global-c-variable/90725 "2007-03-31T14:54:15Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![131313](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/1/da6949/32.png) [@131313](https://www.ruby-forum.com/u/131313)\
**Post date:** [March 31, 2007, 2:54pm UTC](https://www.ruby-forum.com/t/how-to-crash-ruby-by-not-registering-global-c-variable/90725/1 "2007-03-31T14:54:15Z")

</div>

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 ?

---

<div class="post-metadata">

**Author:** ![131313](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/1/da6949/32.png) [@131313](https://www.ruby-forum.com/u/131313)\
**Post date:** [March 31, 2007, 3:09pm UTC](https://www.ruby-forum.com/t/how-to-crash-ruby-by-not-registering-global-c-variable/90725/2 "2007-03-31T15:09:21Z")

</div>

On 3/31/07, 13 [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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.

Your masochistic behavior scares me a little bit ;), but if I  
understand your intention correctly, you don’t _actually_ want to call  
rb\_define\_variable like you do on line 13… I believe calling that  
will cause Ruby to reference the string which is typically a good  
thing, but in this case it’s whats causing you to fail to see the  
fireworks that you seek.

Even if Ruby never references your string, and the garbage collector  
does ‘reap you inadvertently’ you probably wouldn’t see the fireworks  
until you happened to dereference the ‘str’ variable later in your C  
program, and even then only if the memory in question had been filled  
with something interesting in the mean time.

Thats the slippery nature of the descrivbd problem, when you do fall  
victim to it it might be tough to debug, because all you’re going to  
have is _occasionally_ an ‘str’ variable filled with something  
strange.

Hope that helps,  
-Harold

---

<div class="post-metadata">

**Author:** ![131313](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/1/da6949/32.png) [@131313](https://www.ruby-forum.com/u/131313)\
**Post date:** [March 31, 2007, 3:37pm UTC](https://www.ruby-forum.com/t/how-to-crash-ruby-by-not-registering-global-c-variable/90725/3 "2007-03-31T15:37:24Z")

</div>

Oh, I see! Your answer is what I was looking for. Thanks!

If someone is curious here is this cool piece of code:

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 str = rb\_str\_new2(“FooBar”);  
12 /rb\_global\_variable(&str);/ /_ Uncomment this if you don’t  
want SF _/  
13  
14 rb\_eval\_string(“GC.start”);  
15  
16 /_ Boom! Here comes Segmentation fault \*/  
17 printf(“Value: %s\n”, StringValuePtr(str));  
18  
19 ruby\_finalize();  
20 return 0;  
21 }

–  
Martins
