Valgrind and embedded ruby

Hi all,

I'm currently testing an environment with embedding ruby and found an
issue when allocating a large amount of ruby string objects in external
C calls. Im not sure, whether I misunderstood the correct usage.

The Ruby version used is 1.8.4, own compile on red hat EL update 5.

The C environment is:

···

---------------------------------
#include "ruby.h"

int main (int argc, char *argv[])
{
    VALUE cModule;
    VALUE message;

    ruby_init();
    cModule = rb_define_module("CModule");

    rb_require("MemCheck.rb");

    for (long long l=0; l<1000LL; l++) {
  // convert C string to Ruby object
  message = rb_str_new2("C says Hello to Ruby."
            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                              "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                              "ABCDEFGHIJKLMNOPQRSTUVWXYZ");

  rb_funcall(cModule, rb_intern("sendToRuby"), 1, message);
    }

    return 0;
}
-------------------------
The Ruby script:
-------------------------
print("This is Ruby, required MemCheck.rb\n");

module CModule
  def CModule.sendToRuby(msgFromC)
  end
end
--------------------------

If I use valgrind to check for memory leaks, all is OK. If I now change
the loop count from 1000LL to 10000LL, valgrind throws errors:

==7903== Conditional jump or move depends on uninitialised value(s)
==7903== at 0x806C904: gc_mark_children (gc.c:758)
==7903== by 0x806C88F: gc_mark (gc.c:731)
==7903== by 0x806C6C2: mark_locations_array (gc.c:626)
==7903== by 0x806C6EF: rb_gc_mark_locations (gc.c:639)

(in total 496 errors from 39 contexts)

Has anybody seen this behavior? Where am I wrong?

Any help is appreciated, best regards

Heiko

Quoting Heiko Leberer <ihspm@haleb.de>:

If I use valgrind to check for memory leaks, all is OK. If I now
change the loop count from 1000LL to 10000LL, valgrind throws
errors:

==7903== Conditional jump or move depends on uninitialised
value(s)
==7903== at 0x806C904: gc_mark_children (gc.c:758)
==7903== by 0x806C88F: gc_mark (gc.c:731)
==7903== by 0x806C6C2: mark_locations_array (gc.c:626)
==7903== by 0x806C6EF: rb_gc_mark_locations (gc.c:639)

(in total 496 errors from 39 contexts)

This is probably the consequence of the "conservative" portion of
Ruby's garbage collector, which scans the stack and some other
areas which could be uninitialized.

You'll see similar warnings from valgrind in the presence of other
conservative GCs (for example, the boehm collector for C).

This is a consequence of the fact that a conservative collector must
scan memory without knowing whether it is initialized/valid in
advance or not. Conservative collectors are designed to be robust
in the face of garbage pointers, however, so this is perfectly
safe.

-mental

That's great information, thanks.

I was just surprised, that the smaller loop doesn't throw any errors
and as soon as the allocated string objects exceed a given memeory
size, something seems to go wrong. Since Ruby is widely used, that
hinted at an usage error.

Thanks again and best regards,

Heiko

Quoting Heiko Leberer <ihspm@haleb.de>:

I was just surprised, that the smaller loop doesn't throw any
errors and as soon as the allocated string objects exceed a given
memeory size, something seems to go wrong.

There's a bit of a hysteresis in the garbage collection; probably
there aren't any collection passes being triggered until the
allocated space passes a certain threshold.

-mental