GTK and Valgrind

As you may know since the beginning of this year we have for Nim with the compile option --gc:arc a deterministic memory management available (currently only in the devel version of the compiler) which makes it easy to test for memory leaks or corruption. Of course generally there are no leaks or corruptions, as Nim is a high level language, but it is always good to test. So I thought I may do some tests for the Nim GTK bindings.

But before I tried an official C code example, hoping that this would report fine. I took

https://developer.gnome.org/gnome-devel-demos/3.22/button.c.html.en

for first test, as I have a Nim version of that code already, and got

$ gcc `pkg-config gtk+-3.0 --cflags` button.c -o button `pkg-config --libs gtk+-3.0`
stefan@nuc /tmp/hhh $ ./button 
stefan@nuc /tmp/hhh $ valgrind ./button 
==5526== Memcheck, a memory error detector
==5526== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5526== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==5526== Command: ./button
==5526== 
==5526== Source and destination overlap in memcpy_chk(0x1ffeffeb20, 0x1ffeffeb20, 32)
==5526==    at 0x4845DD7: __memcpy_chk (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5526==    by 0x553410E: g_get_language_names_with_category (in /usr/lib64/libglib-2.0.so.0.6200.5)
==5526==    by 0x5557A2B: ??? (in /usr/lib64/libglib-2.0.so.0.6200.5)
==5526==    by 0x5557B6B: g_key_file_new (in /usr/lib64/libglib-2.0.so.0.6200.5)
==5526==    by 0x4B3A06E: gtk_settings_load_from_key_file (in /usr/lib64/libgtk-3.so.0.2404.9)
==5526==    by 0x4B3A79C: gtk_settings_init (in /usr/lib64/libgtk-3.so.0.2404.9)
==5526==    by 0x54DC7C9: g_type_create_instance (in /usr/lib64/libgobject-2.0.so.0.6200.5)
==5526==    by 0x54C522A: ??? (in /usr/lib64/libgobject-2.0.so.0.6200.5)
==5526==    by 0x54C5C43: g_object_new_valist (in /usr/lib64/libgobject-2.0.so.0.6200.5)
==5526==    by 0x54C6710: g_object_new (in /usr/lib64/libgobject-2.0.so.0.6200.5)
==5526==    by 0x4B3DEB8: gtk_settings_get_for_display (in /usr/lib64/libgtk-3.so.0.2404.9)
==5526==    by 0x4ACC737: display_opened_cb (in /usr/lib64/libgtk-3.so.0.2404.9)
==5526== 
==5526== 
==5526== HEAP SUMMARY:
==5526==     in use at exit: 2,419,006 bytes in 27,441 blocks
==5526==   total heap usage: 297,247 allocs, 269,806 frees, 40,037,735 bytes allocated
==5526== 
==5526== LEAK SUMMARY:
==5526==    definitely lost: 5,960 bytes in 14 blocks
==5526==    indirectly lost: 26,324 bytes in 1,102 blocks
==5526==      possibly lost: 5,428 bytes in 55 blocks
==5526==    still reachable: 2,282,798 bytes in 25,484 blocks
==5526==                       of which reachable via heuristic:
==5526==                         length64           : 5,816 bytes in 95 blocks
==5526==                         newarray           : 2,128 bytes in 53 blocks
==5526==         suppressed: 0 bytes in 0 blocks
==5526== Rerun with --leak-check=full to see details of leaked memory
==5526== 
==5526== For lists of detected and suppressed errors, rerun with: -s
==5526== ERROR SUMMARY: 78 errors from 1 contexts (suppressed: 0 from 0)

Well, when for the C code such errors are already reported, then it makes no real sense to test the Nim bindings with Valgrind. Any ideas? Will GTK4 work better?

Well, you may say that the gtk libs may allocate some internal buffers, and next start of the executable will work fine. But I tried starting multiple time, and result is not really better.

I do not know much about valgrind, maybe I am doing something wrong.

Well maybe I should test a plain C program first. So grab one from

https://www.tutorialspoint.com/cprogramming/index.htm

#include <stdio.h>

int main() {
   /* my first program in C */
   printf("Hello, World! \n");
   
   return 0;
}
$ gcc plain.c

$ ./a.out 
Hello, World! 
stefan@nuc /tmp/hhh $ valgrind ./a.out 
==6810== Memcheck, a memory error detector
==6810== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6810== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==6810== Command: ./a.out
==6810== 
Hello, World! 
==6810== 
==6810== HEAP SUMMARY:
==6810==     in use at exit: 0 bytes in 0 blocks
==6810==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==6810== 
==6810== All heap blocks were freed -- no leaks are possible
==6810== 
==6810== For lists of detected and suppressed errors, rerun with: -s
==6810== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Seems to be fine.

Well first of all, you need debug symbols. Then, use the glib.supp file from glib’s git, or you will drown in type registration noise.

Well first of all, you need debug symbols.

Where can I buy them?

But seriously, after thinking about your comment for a few days, I get the feeling that I would have to recompile whole GTK packages from source myself? And then in some way install a glib.supp file on my box? I assume the supp file is something like a list of known and unfixable leaks?

Seems to be some effort. I would assume that the few remaining GTK C coders would all have to do it, to check for leaks and other issues in their C code? Well, maybe then I should do it too to check the Nim bindings :frowning:

Or would just waiting for GTK4 be enough?

It depends on your Linux distribution; modern distros—e.g. Fedora, Debian/Ubuntu—tend to package debugging symbols as separate archives that you can install only when needed—as they occupy a fair amount of space. Other Linux distributions, like Arch, do not have split packages so you’re required to rebuild your own packages with disabled symbol stripping.

On Windows and macOS you’re typically responsible for building your dependencies and then shipping them out yourself, so it’s your decision.

Valgrind suppression files are a list of false positives; these are usually one-off allocations that are collected by the OS once the process terminates, and thus are not classified as “leaks”. A lot of libraries—including ones that are not under the control of the GTK developers—have this particular behaviour. GLib provides its suppression file under ${datadir}/glib-2.0/valgrind, where datadir is the same directory passed when configuring GLib’s build—usually ${prefix}/share.

GTK won’t magically fix any leak that hasn’t been reported, yet. It definitely won’t remove one-off allocations.

2 Likes

Thanks for the detailed explanation.

I am using Gentoo Linux, will consult Gentoo docs how to recompile GTK with debug symbols. Some months ago I already had to recompile glibc with debug symbols to get valgrind working at all, but I can currently not remember details, so I have to consult docs.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.