[Gc] double allocate

Bruce Hoult bruce at hoult.org
Wed Nov 15 18:39:33 PST 2006

On 11/15/06, Boehm, Hans <hans.boehm at hp.com> wrote:
> > So ... is it supposed to be possible to have a block not yet
> > be scanned after the last GC, but also have objects from it
> > be on an object free list?  If this is not normal, could it
> > be caused by GC_free()?
> Not at the end of a collection.  GC_finish_collection() calls
> GC_start_reclaim().  Its first action is to clear both free lists and
> lists of blocks waiting to be reclaimed.
> In the absence of a client bug, GC_free shouldn't be able to provoke
> that situation either.  If GC_free() is called after the block is
> reclaimed, we're fine.  If it's called before the block has been
> reclaimed, it should only be callable on a block that was marked at the
> last GC, and hence won't be touched when the block is later reclaimed.
> Thus it certainly shouldn't end up on the free list as part of the
> reclaim process.

OK, found and fixed this.  It was my fault :-(  I'd made a previous
change to the handling of the mark bits for uncollectable objects to
make it easier to figure out which were in use and which were not.
This involved GC_free() clearing the mark bit for uncollectable
objects.  Unfortunately it was doing it for collectable objects as
well.  I'm not sure whether I thought I'd got that within the scope of
a "if (UNCOLLECTABLE(p)) ..." test, or whether I just didn't think
about it properly but in any case that's what happened.

I found the following function very handy to run from the debugger
while tracking this down.  Perhaps you might consider including it?

void GC_print_free_list(int kind, int sz){
    struct obj_kind * ok = &GC_obj_kinds[kind];
    ptr_t flh = ok -> ok_freelist[sz];
    struct hblk *lastBlock = 0;
    int n = 0;

    while (flh){
        struct hblk *block = HBLKPTR(flh);
        if (block != lastBlock){
            GC_printf1("In heap block at 0x%x", block);
            lastBlock = block;
        GC_printf2("%d: 0x%x", ++n, flh);
        flh = obj_link(flh);

More information about the Gc mailing list