From: "Mauricio Fernández" Date: 2003-04-09T01:53:13+09:00 Subject: Re: [embedding] keeping track of non-exported global variables On Wed, Apr 09, 2003 at 01:14:34AM +0900, Simon Strandgaard wrote: > Im still not getting you point. Sorry. > > You mention some object which is OK to push on the array. > Is there some "kinds of object" which I must avoid storing > in the array ? Invalid values ? Nope, just that when the memory position used to hold the VALUE is reused anything could be there. > What is an invalid value ??? You have class Objects { Objects() { ... rb_gc_register_address(&objects); // now Ruby remembers the address of objects } ~Objects() { } // after the destructor is done, anything could // be placed in the address where the attribute objects used to be. // Ruby could think it is a real object (with a pointer to its klass, // etc) and bomb private: VALUE objects; }; > The only objects I register is Data_Wrap_Struct's. > > > Objects::~Objects() { > /* > question: will this flush the array ? > or do I have to do it manualy? > */ > rb_gc_unregister_address(objects); > } Here's my guess: suppose you don't do rb_gc_unregister_address. Then, Ruby keeps a pointer to the VALUE, even though you object is dead. At some point later in time, another C++ object is living there, so at the address where your VALUE used to live, you now have an int which happens to be some pair number. When doing GC, Ruby will remember the address of that VALUE, check whether it is a Fixnum, and then decide that "it is a real object", so it will ask it to mark all the objects it holds references to. In order to do so it goes retrieve information to wherever the VALUE points to, which is of course wrong. See, in gc.c void rb_gc_mark_children(ptr) VALUE ptr; { register RVALUE *obj = RANY(ptr); .... case T_DATA: if (obj->as.data.dmark) (*obj->as.data.dmark)(DATA_PTR(obj)); // ===== bad break; case T_OBJECT: rb_mark_tbl(obj->as.object.iv_tbl); break; .... } everything will bomb as soon as Ruby does obj-> as it will be following an invalid value. -- _ _ | |__ __ _| |_ ___ _ __ ___ __ _ _ __ | '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ | |_) | (_| | |_\__ \ | | | | | (_| | | | | |_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_| Running Debian GNU/Linux Sid (unstable) batsman dot geo at yahoo dot com People disagree with me. I just ignore them. -- Linus Torvalds, regarding the use of C++ for the Linux kernel