3

I've tried to use libgc (BDW garbage collector) within this simple code.

Note, that reference holded only to last node in a fake "list", so that, living set is only two last nodes.

// thanks to @chill for this example
#include <gc.h>

struct list {
    struct list* next;
};

int main() {
    GC_INIT();
    struct list *last = NULL;
    for (;;) {
        struct list* nuo = GC_MALLOC(sizeof(struct list));
        nuo->next = NULL;
        // if next line is commented, then no leakage
        if (last) last->next = nuo;
        last = nuo;
    }
}

But it could not stay within memory limits:

$ gcc -O0 gc.c -lgc -o gc

$ GC_MAXIMUM_HEAP_SIZE=100000000 ./gc

GC Warning: Out of Memory!  Trying to continue ...
GC Warning: Out of Memory!  Trying to continue ...
GC Warning: Out of Memory!  Trying to continue ...
GC Warning: Out of Memory!  Trying to continue ...
GC Warning: Out of Memory! Heap size: 95 MiB. Returning NULL!
Segmentation fault

What do I do wrong? Ubuntu 15.04 x86_64 gcc 4.9.2 libgc 7.2d-6.4

Update: i've just compiled trunk version from https://github.com/ivmai/bdwgc and it looks to work properly. So that, bug is only in 7.2d or in a version packaged to Ubuntu.

Update: libgc 7.2f compilled from source also works properly. So that it is just Ubuntu's and Debian's version issue.

funny_falcon
  • 427
  • 3
  • 11
  • @leppie, `last` makes only the last allocated element reachable and nothing is reachable from the last allocated element. – chill Jul 13 '15 at 10:47
  • @chill: My bad then ;p – leppie Jul 13 '15 at 10:47
  • the GC heap size is being set to 100 million. probably more than the available memory. Note: the posted code fails to pass the allocated memory to GC_free(). the 'forever' 'for' loop keeps allocating memory until the memory is exhausted. I.E. the program logic needs to be modified to not keep allocating more and more memory. this line: 'last = nuo;' is ok, when last == NULL, after that, it corrupts the linked list – user3629249 Jul 14 '15 at 12:08
  • after the call to GC_MALLOC(), the code should always check (!=NULL) the value in nuo to assure the operation was successful – user3629249 Jul 14 '15 at 12:10

1 Answers1

3

It may just be a bug, but it could be a victim of a false pointer as well. BDWGC is a conservative GC; if a word that "looks like" a pointer that happens to point a GC_malloced memory, the memory is retained. If some false pointer happens to point one of your list node, it will be accidentally retained, and all the nodes pointed from it are also retained.

It is discussed in terms of weak GC robustness. See the following paper for the details:

http://www.hpl.hp.com/techreports/2001/HPL-2001-251.pdf

A common idiom is to manually nullify the next link when the node gets unused.

shirok
  • 141
  • 3
  • True. It’s under the headline "An Embarrassing Failure Scenario". Also found here: http://www.hboehm.info/gc/bounds.html – Ringding Jul 15 '15 at 15:58