1

I created simple GTK program with horizontal box and 2 buttons and it causes huge memory leak.

Here is the code: (you can compile it with gcc main.c `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0`)

#include <gtk/gtk.h>

GtkWidget* playorPauseButton;
GtkWidget* stopButton;

int status = 0;

gboolean updateView(gpointer user_data)
{
    GtkWidget* image;
    
    if (status == 0)
        image=gtk_image_new_from_icon_name ("media-playback-pause",GTK_ICON_SIZE_DND);
    else 
        image=gtk_image_new_from_icon_name ("media-playback-start",GTK_ICON_SIZE_DND);

    gtk_button_set_image((GtkButton*)playorPauseButton,image);

    return TRUE;
}

int main( int argc, char *argv[])
{
    gtk_init(&argc, &argv);

    GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
    
    GtkWidget* hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL,10);

    playorPauseButton = gtk_button_new_from_icon_name("media-playback-start",GTK_ICON_SIZE_DND);
    gtk_box_pack_start((GtkBox*)hbox,playorPauseButton,0,0,0);
    
    stopButton = gtk_button_new_from_icon_name ("media-playback-stop",GTK_ICON_SIZE_DND);
    gtk_widget_set_sensitive(stopButton, FALSE); 
    gtk_box_pack_start((GtkBox*)hbox,stopButton,0,0,0);

    gtk_container_add(GTK_CONTAINER(window), hbox);

    gdk_threads_add_timeout (200, updateView, NULL);

    gtk_widget_show_all (window);

    gtk_main();

    return 0;
}

I run this program and checked memory usage using "echo 0 $(awk '/Private/ {print "+", $2}' /proc/PID/smaps) | bc" command from this thread In Linux, how to tell how much memory processes are using?

This is what i get: (memory is in kB and refreshed every 2 second)

10296
10620
12328
12580
12820
13056
13292
13472
13776
13944
14176
14440
14644
14828
15012

I tested this on 2 platform. One with GTK 3.22.3 and Weston, and second with GTK 3.24.2 and Xorg. In second scenario the Xorg process is growing.

The fun part is that when i comment line "gtk_widget_set_sensitive(stopButton, FALSE);" or "gtk_button_set_image (playorPauseButton,image);" there is 0 memory leak. I don't know what is going on, how setting button sensitivity to FALSE can cause so huge memory leak. Please help me understand this.

In case someone is wondering what i am trying to do, i am trying to create control panel to allow start of machine and stopping it, and i want that stop button to be only active when machine is running.

  • I don't know this lib but one potential bug is that you pass an incorrect callback function pointer. It's supposed to be a `GSourceFunc`: `gboolean (*GSourceFunc) (gpointer user_data);`. But you pass a pointer to an obsolete style function `gboolean (*)()`. That's not a compatible pointer, so depending on compiler, it may work or it might crash. Your compiler ought to give you a warning. – Lundin Dec 17 '20 at 10:32
  • That's not the case, but i updated the code to compile without any warnings. – Łukasz Strugała Dec 17 '20 at 10:52

1 Answers1

1

I'm not sure what's causing the memory leak, but one thing you could do is change the button icon only when the status changes, rather than polling every 1/5th of a second.

This is better for performance, and your UI will update immediately--.2 seconds may not seem like much but it will be noticeable.

James Westman
  • 2,680
  • 1
  • 15
  • 20
  • Hello, thanks for answer. I tested your solutions, using "g_autoptr(GtkWidget) image = NULL;" and with using "g_object_unref(image);" after line "gtk_button_set_image((GtkButton*)playorPauseButton,image);". Both solutions leads to Gtk Critical errors and image doesn't appear inside button. – Łukasz Strugała Dec 31 '20 at 10:15
  • @ŁukaszStrugała Hmm, it's working for me. You didn't try both solutions at once, did you? – James Westman Dec 31 '20 at 17:56
  • No, what version of gtk you use? – Łukasz Strugała Jan 01 '21 at 19:17
  • Ah, now I'm seeing it. I'm using GTK 3.24.24. It looks like gtk_button_set_image *does* transfer the reference, so I'm not sure what's going on here. – James Westman Jan 01 '21 at 21:30