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