[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
smobs and lazy sweeping: the curious incident of the free in the ...
From: |
Andy Wingo |
Subject: |
smobs and lazy sweeping: the curious incident of the free in the ... |
Date: |
Tue, 18 Dec 2007 00:16:11 +0100 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.1.50 (gnu/linux) |
Greets,
I recently tracked down an interesting problem in Guile-GNOME, and
thought that others might want to know about it, to avoid if you have
such a thing in your programs.
The way it would be reproduced goes like this:
(1) Create a SMOB wrapper for a C object. Make a weak cache whereby if
we see this C object again, as in a return from a C function, and
there is a scheme object alive for this C object, we reuse the
existing SMOB.
(2) Later, the wrapper becomes inacessible to Scheme, and thus
collectable. The object lives on in C though.
(3) GC runs, as a result of e.g. needing cells for allocating objects
in Scheme. All objects are marked, and some collectable objects are
swept. The rest will be swept as needed -- this is the "lazy
sweeping" feature of Guile 1.8's GC. Our SMOB wrapper is marked as
collectable, but is not swept.
(4) Go to create another wrapper for that same C object. Since the
SMOB has not been swept -- its free() function has not been run --
we think it is valid and return it, although it is still marked as
collectable!
(5) The card that the SMOB is in is swept, its free() function is
called, its type changed to scm_t_free_cell, *but the SCM value
still lives in Scheme-land*. Future attempts to access it raise all
kinds of weird errors. Boom!
So the "solution" that I introduced is that when retrieving cached SCM
values for C objects, we call scm_gc_mark() on the object, thus
reprieving it from the reaper's scythe. But man, it took me about four
days to find it!
Peace,
Andy
--
http://wingolog.org/
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- smobs and lazy sweeping: the curious incident of the free in the ...,
Andy Wingo <=