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;
}

Reply via email to