[plt-scheme] garbage collection questions
> At Wed, 21 Feb 2007 10:13:59 -0000 (GMT), "Dave Griffiths" wrote:
>> In a function extension, does the argv argument have to be protected from
>> garbage collector in _every_ function which can result in a scheme
>> allocation?
>
> Yes. In
>
> Scheme_Object f(int argc, Scheme_object **argv) {
> ...
> scheme_do_something(...);
> ...
> ... argv[0] ...
> }
>
> the caller of `f' may well have GC-registered a reference to the same
> array as `argv', in which case the array referenced by `argv' won't get
> collected during scheme_do_something(). But the array might get moved. So,
> `argv' definitely needs to be registered with the GC; that way, if
> scheme_do_something() causes the array to move, `argv' points to the new
> location on return.
>
>> Following on from this, is there documentation on which scheme api
>> functions contain an allocation call? Is it safer to just protect all
>> Scheme_Object pointers in every function extension regardless?
>
> The latter. The documentation says
>
> Garbage collection can occur during any call into MzScheme or its
> allocator, on anytime that MzScheme has control, except during
> functions that are documented otherwise.
>
> Very few functions are documented otherwise. I think the vast majority of
> scheme_...() functions can, in fact, allocate.
>
> You can assume that macros named using ALL_CAPS_AND_UNDERLINES() do not
> allocate. For example, SCHEME_INTP() and SCHEME_INT_VAL() do not allocate.
>
> In "schemef.h", a number of functions are marked by XFORM_NON_GCING.
> That's a compilation hint to the xform tool, and is not actually meant as
> a part of the public API (i.e., don't rely on the annotations).
Sorry for the lack of RTFM on my part. That's great info though. I also
read your initial post about 3m after sending that email that helped a lot
to explain the underlying details and motivation:
http://list.cs.brown.edu/pipermail/plt-scheme/2006-June/013801.html
>> Is there a way of running the garbage collector in a more deterministic
>> manner - ie, make it run in a slow "debug" mode, freeing all availible
>> memory at every opportunity (or is this what 3m does anyway) and then
>> making it possible to check (with valgrind or similar) for strangeness,
>> as a way of verifying extension code.
>
> Configure with --enable-compact, and then change the #define of CHECKS
> from 0 to 1 in "src/mzscheme/gc2/compact.c". This increases the number of
> consistency checks, but it's a long way for GCing at every
> opportunity (which would be prohibitively slow). You can change
> GROW_FACTOR to something closer to 1 to trigger more frequent
> collections.
I suspect that will do the trick for me - I had to spend a long time
tracking down some very occasional crashes caused by a simple
misunderstanding of the gc macros, anything to make potentially dodgy code
fail faster is good.
>> I also am having difficulty running tools like valgrind or gdb on
>> recent SVN versions of mzscheme.
>
> I don't know about Valgrind, but a common confusion with gdb under Linux
> is that you get a seg fault from 3m almost immediately on
> startup. That's because the GC uses page protection to implement write
> barriers.
>
> Tell gdb to ignore SIGSEGV:
>
> (gdb) handle SIGSEGV nostop noprint
>
> and then continue. When there's a seg fault that doesn't look like a write
> to a GC-protected page, the GC's signal handler will call
> abort().
That's the one, thanks - I suspect there is a similar fix for valgrind,
I'll check it out.
Many thanks again,
dave