[Kde-bindings] Ruby 1.9.x GC.stress + qtruby ([BUG] object allocation during garbage collection phase)

Richard Dale rdale at foton.es
Mon Mar 16 18:36:53 UTC 2009


On Thursday 12 March 2009 17:15:51 Davor Ocelic wrote:
> Hello folks,
>
> We have noticed an issue with qtruby and Ruby 1.9.x when
> GC.stress= true.
>
> When the GC is marking objects, and it encounters any kind of
> Qt layout, it uses itemAt() to dive in and access individual
> contained widgets.
>
> It calls respond_to() to see whether itemAt() is redefined
> in Ruby; if not (which is most of the time), before the first
> call to Qt's itemAt(), it tries to intern the method name,
> which in Ruby 1.9.x creates a new string, but object creation
> is not allowed during garbage collection phase.
>
> So the program fails with an error
>  "[BUG] object allocation during garbage collection phase"
>
>
> The quick solution to the problem is interning the symbols
> manually, before layouts are used. For example, just
> saying:
>
>   ...
>   'itemAt'.intern
>   ...
>   l= Qt::HBoxLayout.new...
>
>
> I think this may be affecting all types of Qt objects
> that can contain other widgets (not just layouts).
> (Just of course it would not be itemAt() but some other
> function.)
>
> Would the right solution be to add support for this
> directly in qtruby and intern the needed method names
> there automatically, before they are used by GC?
I've just added some code the intern the method name strings when QtRuby 
starts up. I forgot the cc the commit to this list, so here is what it looked 
like:

    // A problem has been found with QtRuby when it is run with Ruby 1.9.1
    // and GC.stess is true.
    // In the smokeruby_mark() function called during garbage collection, 
    // any virtual methods which are called on the instances being checked 
    // could have overriden by Ruby methods.  So the Wt::Ruby runtime uses 
    // 'respond_to()' to find out whether they have been overriden.
    // However, this involves calling 'rb_intern()' on the method name,
    // which means memory could be allocated, giving an error when running 
under
    // GC.stress mode. So workround it by pre-allocating any strings with
    // rb_intern() for all the C++ methods used in smokeruby_mark()
    rb_intern("children");
    rb_intern("childItems");
    rb_intern("childCount");
    rb_intern("child");
    rb_intern("hasChildren");
    rb_intern("parent");
    rb_intern("parentItem");
    rb_intern("item");
    rb_intern("items");
    rb_intern("rowCount");
    rb_intern("rowAt");
    rb_intern("columnCount");
    rb_intern("elementAt");
    rb_intern("columnAt");
    rb_intern("topLevelItem");
    rb_intern("itemAt");
    rb_intern("internalPointer");

-- Richard



More information about the Kde-bindings mailing list