I'm trying to integrate the Boehm garbage collector with GLib in Linux, but in one case I have found that it is not freeing the memory: when I call g_strsplit many times, it will run out of memory and segfault. The README for the garbage collector warned that it may have trouble finding pointers inside of dynamic libraries, and may require the use of GC_add_roots.
To test this, I copied all the relevant code from GLib into my source file, not linking against libglib-2.0.so at all. This eliminated the segfaults, which tells me this is indeed the problem. However, there is no documentation on how to use GC_add_roots to resolve this. Can someone help me?
Here is the code that causes the memory leak:
#include <glib.h>
#include <gc.h>
void no_free(void *mem) {}
int main() {
g_mem_gc_friendly = TRUE;
GMemVTable memvtable = {
.malloc = GC_malloc,
.realloc = GC_realloc,
.free = no_free,
.calloc = NULL,
.try_malloc = NULL,
.try_realloc = NULL
};
g_mem_set_vtable(&memvtable);
for (int i = 0; i < 10000; i++) {
char **argv = g_strsplit("blah", " ", 0);
argv[0][0] = 'a'; // avoid unused variable warning
}
return 0;
}
Since GLib 2.46, g_mem_set_vtable()
does nothing, so there is no way to get this working at the GLib level using a modern GLib. GLib now unconditionally uses the allocator from libc when you call g_malloc()
, g_new()
, etc. It does still use its own GSLice
allocator when you explicitly use g_slice_*()
, but that requests its block allocations from the libc allocator too.
I suggest you try to integrate the garbage collector at the libc level instead. There’s an old article about implementing that using glibc’s malloc hooks, which are essentially the same as GMemVTable
, but at the glibc level instead of the GLib level. I haven’t tried this, so I don’t know how well it works in practice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With