Memory leaks, valgrind and G_SLICE

Hello glib hackers, I struggle to understand something about memory and G_SLICE env var. It seems that, depending on the value of G_SLICE, that some memory leak are hidden.

let’s take the following snippet where I purposely skipped memory free.

#include <glib.h>

gint main(gint argc, gchar** argv)
{
    GByteArray *array = g_byte_array_new();
    guint8* data = g_malloc (2 * sizeof(guint8));
    g_byte_array_append (array, data, 2);
    // Should call: g_byte_array_free(toto, FALSE);
    g_free (data);
    return 0;
}

Compile the program and run a “raw” valgrind (without any env var):

 gcc `pkg-config --cflags glib-2.0` test_glib.c `pkg-config --libs glib-2.0` -o test_glib && valgrind --show-leak-kinds=definite --suppressions=/usr/lib/valgrind/glib.supp ./test_glib
==21189== Memcheck, a memory error detector
==21189== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==21189== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==21189== Command: ./test_glib
==21189== 
==21189== 
==21189== HEAP SUMMARY:
==21189==     in use at exit: 18,668 bytes in 8 blocks
==21189==   total heap usage: 9 allocs, 1 frees, 18,670 bytes allocated
==21189== 
==21189== LEAK SUMMARY:
==21189==    definitely lost: 40 bytes in 1 blocks
==21189==    indirectly lost: 16 bytes in 1 blocks
==21189==      possibly lost: 0 bytes in 0 blocks
==21189==    still reachable: 18,612 bytes in 6 blocks
==21189==         suppressed: 0 bytes in 0 blocks
==21189== Rerun with --leak-check=full to see details of leaked memory
==21189== 
==21189== For lists of detected and suppressed errors, rerun with: -s
==21189== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

The leak is correctly seen, now do the same with usual en var suggested by the glib doc when dealing with memory checker tool (GLib – 2.0: Running GLib Applications)

G_SLICE=all G_DEBUG=gc-friendly  valgrind --show-leak-kinds=definite --suppressions=/usr/lib/valgrind/glib.supp ./test_glib
==21676== Memcheck, a memory error detector
==21676== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==21676== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==21676== Command: ./test_glib
==21676== 
==21676== 
==21676== HEAP SUMMARY:
==21676==     in use at exit: 59,620 bytes in 12 blocks
==21676==   total heap usage: 13 allocs, 1 frees, 59,622 bytes allocated
==21676== 
==21676== LEAK SUMMARY:
==21676==    definitely lost: 0 bytes in 0 blocks
==21676==    indirectly lost: 0 bytes in 0 blocks
==21676==      possibly lost: 0 bytes in 0 blocks
==21676==    still reachable: 59,620 bytes in 12 blocks
==21676==         suppressed: 0 bytes in 0 blocks
==21676== Rerun with --leak-check=full to see details of leaked memory
==21676== 
==21676== For lists of detected and suppressed errors, rerun with: -s
==21676== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Here we do not see the leak anymore, It seems to came from debug-blocks options of G_SLICE (since all stands for always-malloc:debug-blocks) because not setting it make the leak viewable again:

G_SLICE=always-malloc G_DEBUG=gc-friendly  valgrind --show-leak-kinds=definite --suppressions=/usr/lib/valgrind/glib.supp ./test_glib
==21729== Memcheck, a memory error detector
==21729== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==21729== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==21729== Command: ./test_glib
==21729== 
==21729== 
==21729== HEAP SUMMARY:
==21729==     in use at exit: 18,668 bytes in 8 blocks
==21729==   total heap usage: 9 allocs, 1 frees, 18,670 bytes allocated
==21729== 
==21729== LEAK SUMMARY:
==21729==    definitely lost: 40 bytes in 1 blocks
==21729==    indirectly lost: 16 bytes in 1 blocks
==21729==      possibly lost: 0 bytes in 0 blocks
==21729==    still reachable: 18,612 bytes in 6 blocks
==21729==         suppressed: 0 bytes in 0 blocks
==21729== Rerun with --leak-check=full to see details of leaked memory
==21729== 
==21729== For lists of detected and suppressed errors, rerun with: -s
==21729== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

It seems a pretty obvious usage of glib data structure and I’m wondering what I missing here, is someone that used to track memory leaks in glib can bring me help here ?

Thanks in advance guys.

I don’t know what’s going on with debug-blocks, but you shouldn’t need to set G_SLICE when using valgrind. GLib detects that it’s running under valgrind and automatically sets G_SLICE=always-malloc.

Ok thanks, I’ll do that from now and don’t set G_SLICE anymore

For my curiosity what are the usage of G_SLICE=debug-blocks if we should not use it under valgrind ? I mean, in what scenario do you use it and how ?

No idea, I’ve never used it. Sorry. You’ll have to dig through the code yourself if you want to work out what it does :slight_smile:

Alright then, challenge accepted :wink: I’ll try to find some time to discover what it does

1 Like