Howdy, I'm running debian unstable with the latest libs. I first learned about memprof after Graham Ashtons email a week ago. I have not yet tested libglade and pygtk2. But a simple loop that creates and adds a gtk.Label to a window and then destroy() or remove() the label does not leak any memory.
Then I started testing a simple window with only a simple button inside. (This is pygtk2.) When there is no callback connected to the 'clicked' signal there is no memory leak. But when we connect the 'clicked' signal to a function that print "Hello World", the program leak memory. The same program in C does not leak. Attached is a C and a Python program that when you click on the button once, it will start a timeout loop that click on the button every millisecond. The C program can run forever without using more memory, but the python program will start eating all my memory. How can I compile the pygtk bindings so I can get more info? The stack trace in the memprof window display only (???) as function and file name when I click the "Leaks" button, and lots of lines like this: memprof: /lib/libutil-2.2.5.so: No symbols memprof: /lib/libdl-2.2.5.so: No symbols memprof: /usr/lib/libpython2.2.so.0.0: No symbols memprof: /usr/lib/python2.2/lib-dynload/_codecs.so: No symbols memprof: /usr/lib/python2.2/lib-dynload/struct.so: No symbols memprof: /usr/lib/libmemintercept.so: No symbols memprof: /usr/bin/python2.2: No symbols is printed. The pygtk bindings (gtkmodule.so and friends) are not mentioned on stdout. -- Tom Cato Amundsen <[EMAIL PROTECTED]> GNU Solfege - free eartraining, http://www.gnu.org/software/solfege/
#!/usr/bin/python2.2 import sys sys.path.insert(0, "/home/tom/pygtk2/lib/python2.2/site-packages") import gtk class Win(gtk.Window): def __init__(self): gtk.Window.__init__(self) self.connect('destroy', gtk.mainquit) self.b = b = gtk.Button("test") self.add(b) b.connect('clicked', self.on_click) self.show_all() def do_click(self, *v): print "doclick" self.b.clicked() def on_click(self, w): print "Hello World. Adding new timeout" gtk.timeout_add(1, self.do_click) w = Win() w.show() gtk.mainloop()
all: gcc -Wall -O0 -g leakc.c -o leakc `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`
#include <gtk/gtk.h> GtkWidget *button; /* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */ void doclick( gpointer data) { g_print ("doclick\n"); gtk_button_clicked( GTK_BUTTON(button)); } void hello( GtkWidget *widget, gpointer data ) { g_print ("Hello World. Adding new timeout.\n"); gtk_timeout_add(1, G_CALLBACK(doclick), NULL); } gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data ) { /* If you return FALSE in the "delete_event" signal handler, * GTK will emit the "destroy" signal. Returning TRUE means * you don't want the window to be destroyed. * This is useful for popping up 'are you sure you want to quit?' * type dialogs. */ g_print ("delete event occurred\n"); /* Change TRUE to FALSE and the main window will be destroyed with * a "delete_event". */ return FALSE; } /* Another callback */ void destroy( GtkWidget *widget, gpointer data ) { gtk_main_quit (); } int main( int argc, char *argv[] ) { /* GtkWidget is the storage type for widgets */ GtkWidget *window; /*GtkWidget *entry;*/ /* This is called in all GTK applications. Arguments are parsed * from the command line and are returned to the application. */ gtk_init (&argc, &argv); /* create a new window */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); /* When the window is given the "delete_event" signal (this is given * by the window manager, usually by the "close" option, or on the * titlebar), we ask it to call the delete_event () function * as defined above. The data passed to the callback * function is NULL and is ignored in the callback function. */ g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (delete_event), NULL); /* Here we connect the "destroy" event to a signal handler. * This event occurs when we call gtk_widget_destroy() on the window, * or if we return FALSE in the "delete_event" callback. */ g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL); /* Sets the border width of the window. */ gtk_container_set_border_width (GTK_CONTAINER (window), 10); /* Create the entry */ /*entry = gtk_entry_new (); gtk_container_add (GTK_CONTAINER (window), entry); gtk_widget_show (entry);*/ button = gtk_button_new_with_label("test"); gtk_container_add (GTK_CONTAINER (window), button); gtk_widget_show (button); g_signal_connect( G_OBJECT(button), "clicked", G_CALLBACK(hello), NULL); /* and the window */ gtk_widget_show (window); /* All GTK applications must have a gtk_main(). Control ends here * and waits for an event to occur (like a key press or * mouse event). */ gtk_main (); return 0; }