Sign up

Pages: 1 2

Memory leak in Pixbuf ctor/dtor?

I created a simple image viewer in gtkD, which eats up memory every time a new image is displayed. The "same" program in C doesn't show that issue. Looking into src/gdk/Pixbuf.d I can't see the problem immediately.

What am I doing wrong?

C code:

// gcc dvgtk.c $(pkg-config --cflags --libs gtk+-3.0) -o dvgtk

#include <gtk/gtk.h>

static	GError		*err = NULL;
static	GdkPixbuf	*pixbuf = NULL;
static	GtkWidget	*window, *image;
static	int		filenameidx;
static	char const	*pfilenames[] = {
						"image1.jpg",
						"image2.jpg"
					};

static gboolean TimeoutFunc(gpointer user_data)
{
	char const *pfilename;

	pfilename = pfilenames[filenameidx];
	if (++filenameidx >= sizeof(pfilenames) / sizeof(pfilenames[0])) filenameidx = 0;

	if (pixbuf != NULL) {
		g_object_unref(pixbuf);
	}

	pixbuf = gdk_pixbuf_new_from_file(pfilename, &err);
	g_assert_no_error(err);

	gtk_image_set_from_pixbuf((GtkImage*)image, pixbuf);
}

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

	gtk_init(&argc, &argv);

	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), 600, 400);
	gtk_window_set_title(GTK_WINDOW(window), "Image Test");
	gtk_window_set_resizable(GTK_WINDOW(window), FALSE);

	image = gtk_image_new();
	gtk_container_add(GTK_CONTAINER(window), image);

	g_timeout_add(1000, TimeoutFunc, NULL);

	g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
	gtk_widget_show_all(window);

	gtk_main();

	return 0;
}

D code:

import core.memory;

import glib.Timeout;

import gdk.Pixbuf;

import gtk.Image;
import gtk.Main;
import gtk.MainWindow;

private class MyMainWindow : MainWindow
{
	private	int		iteration;
	private	Pixbuf		pixbuf;
	private	Image		image;
	private	size_t		filenameIdx;
	private	string[]	filenames = [
							"image1.jpg",
							"image2.jpg",
						];

	public this(string text)
	{
		super(text);

		this.setDefaultSize(600, 400);
		this.setResizable(false);

		this.image = new Image();
		this.add(this.image);

		new Timeout(1000, &this.cbTimer);
	}

	private bool cbTimer()
	{
		auto filename = this.filenames[this.filenameIdx];
		if (++this.filenameIdx >= this.filenames.length) this.filenameIdx = 0;

		if (this.pixbuf) {
			// these lines don't help anything and can be left out
			this.pixbuf.destroy();
			this.pixbuf = null;
			core.memory.GC.collect();
		}
		this.pixbuf = new Pixbuf(filename);
		this.image.setFromPixbuf(this.pixbuf);

		// stop after 20 image switches to avoid out of memory
		return ++this.iteration < 20;
	}
}

void main(string[] args)
{
	Main.init(args);
	MainWindow win = new MyMainWindow("Image Test");
	win.showAll();

	Main.run();
}

Of course, the actual program is way bigger.

Replace "image1.jpg" and "image2.jpg" with names existing on your system.

Here's some valgrind output. Note that the blocks are meantioned 19 times (which is the switch count of the images):

==00:00:22:00.319 14646== 3,192 (1,520 direct, 1,672 indirect) bytes in 19 blocks are definitely lost in loss record 7,409 of 7,506
==00:00:22:00.319 14646==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==00:00:22:00.319 14646==    by 0x5C75610: g_malloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:22:00.319 14646==    by 0x5C8B22D: g_slice_alloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:22:00.319 14646==    by 0x5C8B76D: g_slice_alloc0 (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:22:00.320 14646==    by 0x9351DB1: g_type_create_instance (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4002.0)
==00:00:22:00.320 14646==    by 0x9336354: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4002.0)
==00:00:22:00.320 14646==    by 0x93384C3: g_object_new_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4002.0)
==00:00:22:00.320 14646==    by 0x93388A3: g_object_new (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4002.0)
==00:00:22:00.320 14646==    by 0x6A2FD2B: gdk_pixbuf_new_from_data (in /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0.3000.7)
==00:00:22:00.320 14646==    by 0x6A2DA01: gdk_pixbuf_new (in /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0.3000.7)
==00:00:22:00.320 14646==    by 0x11BE46E0: ??? (in /usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-jpeg.so)
==00:00:22:00.320 14646==    by 0x6A31B41: gdk_pixbuf_new_from_file (in /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0.3000.7)
==00:00:22:00.320 14646==    by 0x6D0492: _D3gdk6Pixbuf6Pixbuf6__ctorMFAyaZC3gdk6Pixbuf6Pixbuf (in dvgtkd)
==00:00:22:00.320 14646==    by 0x6B1755: _D6dvgtkd12MyMainWindow7cbTimerMFZb (dvgtkd.d:54)
==00:00:22:00.320 14646==    by 0x6F3648: _D4glib7Timeout7Timeout16callAllListenersMFZb (in dvgtkd)
==00:00:22:00.320 14646==    by 0x6F35E4: _D4glib7Timeout7Timeout15timeoutCallbackUC4glib7Timeout7TimeoutZb (in dvgtkd)
==00:00:22:00.320 14646==    by 0x5C70702: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:22:00.320 14646==    by 0x5C6FCE4: g_main_context_dispatch (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:22:00.320 14646==    by 0x5C70047: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:22:00.320 14646==    by 0x5C70309: g_main_loop_run (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:22:00.320 14646==    by 0xC2E8FE4: gtk_main (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.1000.8)
==00:00:22:00.320 14646==    by 0x813162: _D3gtk4Main4Main3runFZv (in dvgtkd)
==00:00:22:00.320 14646==    by 0x6B17EF: _Dmain (dvgtkd.d:67)
==00:00:22:00.320 14646==    by 0x950252: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv (in dvgtkd)
==00:00:22:00.320 14646==    by 0x9501A5: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (in dvgtkd)
==00:00:22:00.320 14646==    by 0x95020B: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv (in dvgtkd)
==00:00:22:00.320 14646==    by 0x9501A5: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (in dvgtkd)
==00:00:22:00.320 14646==    by 0x950126: _d_run_main (in dvgtkd)
==00:00:22:00.320 14646==    by 0x6BFE9C: main (in dvgtkd)
==00:00:22:00.320 14646== 
...
==00:00:22:00.320 14646== 
==00:00:22:00.320 14646== 745,524,612 bytes in 19 blocks are possibly lost in loss record 7,506 of 7,506
==00:00:22:00.320 14646==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==00:00:22:00.320 14646==    by 0x6A2D9CC: gdk_pixbuf_new (in /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0.3000.7)
==00:00:22:00.320 14646==    by 0x11BE46E0: ??? (in /usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-jpeg.so)
==00:00:22:00.320 14646==    by 0x6A31B41: gdk_pixbuf_new_from_file (in /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0.3000.7)
==00:00:22:00.320 14646==    by 0x6D0492: _D3gdk6Pixbuf6Pixbuf6__ctorMFAyaZC3gdk6Pixbuf6Pixbuf (in dvgtkd)
==00:00:22:00.360 14646==    by 0x6B1755: _D6dvgtkd12MyMainWindow7cbTimerMFZb (dvgtkd.d:54)
==00:00:22:00.360 14646==    by 0x6F3648: _D4glib7Timeout7Timeout16callAllListenersMFZb (in dvgtkd)
==00:00:22:00.360 14646==    by 0x6F35E4: _D4glib7Timeout7Timeout15timeoutCallbackUC4glib7Timeout7TimeoutZb (in dvgtkd)
==00:00:22:00.360 14646==    by 0x5C70702: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:22:00.360 14646==    by 0x5C6FCE4: g_main_context_dispatch (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:22:00.360 14646==    by 0x5C70047: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:22:00.360 14646==    by 0x5C70309: g_main_loop_run (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:22:00.360 14646==    by 0xC2E8FE4: gtk_main (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.1000.8)
==00:00:22:00.360 14646==    by 0x813162: _D3gtk4Main4Main3runFZv (in dvgtkd)
==00:00:22:00.360 14646==    by 0x6B17EF: _Dmain (dvgtkd.d:67)
==00:00:22:00.360 14646==    by 0x950252: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv (in dvgtkd)
==00:00:22:00.360 14646==    by 0x9501A5: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (in dvgtkd)
==00:00:22:00.360 14646==    by 0x95020B: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv (in dvgtkd)
==00:00:22:00.360 14646==    by 0x9501A5: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (in dvgtkd)
==00:00:22:00.360 14646==    by 0x950126: _d_run_main (in dvgtkd)
==00:00:22:00.360 14646==    by 0x6BFE9C: main (in dvgtkd)

I'm using GtkD-2.4.0, but had the same problem with GtkD-2.3.1.

Thanks for your help,
Diez

PS: Got

500 - Internal Server Error

Internal Server Error

Internal error information:
object.Exception@../../../root/.dub/packages/vibe-d-0.7.19/source/vibe/utils/dictionarylist.d(134): Accessing non-existent key 'confirmemail'.

vibenews(pure @safe bool std.exception.enforce!(bool).enforce(bool, lazy const(char)[], immutable(char)[], uint)+0x22) [0x846ded2]
vibenews(const(pure @safe immutable(char)[] function(immutable(char)[])) vibe.utils.dictionarylist.DictionaryList!(immutable(char)[], true).DictionaryList.opIndex+0x6c) [0x83e0344]
vibenews(void vibenews.web.WebInterface.postArticle(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse)+0x1fc) [0x830692c]
vibenews(void vibe.http.router.URLRouter.handleRequest(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse)+0xff) [0x83cd837]
vibenews(bool vibe.http.server.handleRequest(vibe.core.stream.Stream, vibe.core.net.TCPConnection, vibe.http.server.HTTPServerListener, ref vibe.http.server.HTTPServerSettings, ref bool)+0xf74) [0x83d1f2c]
vibenews(void vibe.http.server.handleHTTPConnection(vibe.core.net.TCPConnection, vibe.http.server.HTTPServerListener)+0xc7) [0x83d0f07]
vibenews(void vibe.http.server.listenHTTPPlain(vibe.http.server.HTTPServerSettings, void delegate(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse)).doListen(vibe.http.server.HTTPServerSettings, vibe.http.server.HTTPServerListener, immutable(char)[]).lambda4(vibe.core.net.TCPConnection)+0x1f) [0x83ce2f7]<br>vibenews(void vibe.core.drivers.libevent2_tcp.onConnect(int, short, void*).ClientTask.execute()+0x221) [0x837e081]<br>vibenews(_D4vibe4core4core12T7runTaskZ7runTaskFDFZvZS4vibe4core4task4Task12callDelegateFC4vibe4core4core8CoreTaskZv+0x1f) [0x836ff17]
vibenews(void vibe.core.core.CoreTask.run()+0xca) [0x836d252]
vibenews(void core.thread.Fiber.run()+0x21) [0x8482171]
vibenews(fiber_entryPoint+0x49) [0x84820a9]
[(nil)]

Re: Memory leak in Pixbuf ctor/dtor?

On Mon, 03 Nov 2014 15:42:51 GMT, Diez wrote:

What am I doing wrong?

I think that one thread before your question may answer your question: here!

Matheus.

Re: Memory leak in Pixbuf ctor/dtor?

I think that one thread before your question may answer your question: here!

If I change the code:

...
if (this.pixbuf) {
//	this.pixbuf.destroy();	// this line is left out
	this.pixbuf.unref();	// this line is new
	delete this.pixbuf;	// this line is new
	this.pixbuf = null;
	core.memory.GC.collect();
}
this.pixbuf = new Pixbuf(filename);
...

the memory leak seams more slowly, but it's still there. So still not usable for a program running 24/7. Also, I get 9 times (after every 2nd image switch):

GLib-GObject-CRITICAL **: gobjectunref: assertion 'GISOBJECT (object)' failed

With this code:

...
if (this.pixbuf) {
	this.pixbuf.destroy();	// this line in again
	this.pixbuf.unref();	// this line is new
	delete this.pixbuf;	// this line is new
	this.pixbuf = null;
	core.memory.GC.collect();
}
this.pixbuf = new Pixbuf(filename);
...

the program SEGVs as soon as the 'if' body is run.

As I understand D, the entire 'if' block should be unnecessary, since D manages garbage collection under the hood. In case of gtkD, the Pixbuf dtor should handle the reference count of gdkPixbuf.

Any other suggestions?
Diez

Re: Memory leak in Pixbuf ctor/dtor?

On Mon, 03 Nov 2014 19:38:05 GMT, Diez wrote:

Any other suggestions?

Well, in my case I had this problem earlier and I fix with:

In Pixbuf.d I created the following dtor:

~this(){
    this.gdkPixbuf = null;
    this.unref();
}

And in my program I use in this way:

if(!(pixbuf is null)){
    delete pixbuf;
}
pixbuf = new Pixbuf(dr, x, y, w, h);


Note that I'm generating a new buffer from the drawable, while you are creating a new one from an Image, I don't know how this is handled internally, I need to check the code which I'll do when I get home.

Matheus.

Re: Memory leak in Pixbuf ctor/dtor?

On Mon, 03 Nov 2014 19:38:05 GMT, Diez wrote:

Any other suggestions?

Well, I tried the sample code bellow and I didn't see any memory leak (I'm calling drawImg() every 300 ms):

void drawImg(Context cr){    
    static bool change = true;
            
    if(!(pixbuf is null)){
        delete pixbuf;
    }          
    
    auto fimg = visible ? "teste.png" : "teste2.png";
            
    pixbuf = new Pixbuf(fimg);
    cr.setSourcePixbuf(pixbuf, 0, 0);
    cr.paint();
    
    change = !change;
}

Remembering that in my gtkD Pixbuf.d source I wrote a dtor:

~this(){        
    this.gdkPixbuf = null;
    this.unref();
}

Matheus.

Re: Memory leak in Pixbuf ctor/dtor?

Thanks for your reply, Matheus.

To avoid changing gtkD's Pixbuf.d, I sub-classed it. To verify its effect, I added printouts in the ctor and dtor:

import glib.Timeout;

import gdk.Pixbuf;

import gtk.Image;
import gtk.Main;
import gtk.MainWindow;

public class MyPixbuf : gdk.Pixbuf.Pixbuf
{
	public this(string filename)
	{
		super(filename);
		std.stdio.stdout.writeln("MyPixbuf");
	}

	~this()
	{
		std.stdio.stdout.writeln("~MyPixbuf");
		this.gdkPixbuf = null;
		this.unref();
	}
}

private class MyMainWindow : MainWindow
{
	private	int		iteration;
	private	MyPixbuf	pixbuf;
	private	Image		image;
	private	size_t		filenameIdx;
	private	string[]	filenames = [
							"image1.jpg",
							"image2.jpg",
						];

	public this(string text)
	{
		super(text);

		this.setDefaultSize(600, 400);
		this.setResizable(false);

		this.image = new Image();
		this.add(this.image);

		new Timeout(1000, &this.cbTimer);
	}

	private bool cbTimer()
	{
		auto filename = this.filenames[this.filenameIdx];
		if (++this.filenameIdx >= this.filenames.length) this.filenameIdx = 0;

		if (this.pixbuf) {
			delete this.pixbuf;
		}
		this.pixbuf = new MyPixbuf(filename);
		this.image.setFromPixbuf(this.pixbuf);

		// stop after 20 image switches to avoid out of memory
		return ++this.iteration < 20;
	}
}

void main(string[] args)
{
	Main.init(args);
	auto win = new MyMainWindow("Image Test");
	win.showAll();

	Main.run();
}

I get the following output:

MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
(dvgtkd:21102): GLib-CRITICAL **: Source ID 7 was not found when attempting to remove it

Since 10 times the dtor had problems, the memory leak still remains for 9 blocks (why not 10?):

==00:00:01:23.908 21109== 272,753,892 bytes in 9 blocks are possibly lost in loss record 7,504 of 7,504
==00:00:01:23.908 21109==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==00:00:01:23.908 21109==    by 0x6A2D9CC: gdk_pixbuf_new (in /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0.3000.7)
==00:00:01:23.908 21109==    by 0x11BE46E0: ??? (in /usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-jpeg.so)
==00:00:01:23.908 21109==    by 0x6A31B41: gdk_pixbuf_new_from_file (in /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0.3000.7)
==00:00:01:23.908 21109==    by 0x6D0B82: _D3gdk6Pixbuf6Pixbuf6__ctorMFAyaZC3gdk6Pixbuf6Pixbuf (in dvgtkd)
==00:00:01:23.908 21109==    by 0x6B1784: _D6dvgtkd8MyPixbuf6__ctorMFAyaZC6dvgtkd8MyPixbuf (dvgtkd.d:24)
==00:00:01:23.908 21109==    by 0x6B1968: _D6dvgtkd12MyMainWindow7cbTimerMFZb (dvgtkd.d:73)
==00:00:01:23.908 21109==    by 0x6F3D38: _D4glib7Timeout7Timeout16callAllListenersMFZb (in dvgtkd)
==00:00:01:23.908 21109==    by 0x6F3CD4: _D4glib7Timeout7Timeout15timeoutCallbackUC4glib7Timeout7TimeoutZb (in dvgtkd)
==00:00:01:23.908 21109==    by 0x5C70702: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:01:23.908 21109==    by 0x5C6FCE4: g_main_context_dispatch (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:01:23.908 21109==    by 0x5C70047: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:01:23.908 21109==    by 0x5C70309: g_main_loop_run (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:01:23.908 21109==    by 0xC2E8FE4: gtk_main (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.1000.8)
==00:00:01:23.908 21109==    by 0x813852: _D3gtk4Main4Main3runFZv (in dvgtkd)
==00:00:01:23.908 21109==    by 0x6B19FF: _Dmain (dvgtkd.d:87)
==00:00:01:23.908 21109==    by 0x950942: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv (in dvgtkd)
==00:00:01:23.909 21109==    by 0x950895: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (in dvgtkd)
==00:00:01:23.909 21109==    by 0x9508FB: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv (in dvgtkd)
==00:00:01:23.909 21109==    by 0x950895: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (in dvgtkd)
==00:00:01:23.909 21109==    by 0x950816: _d_run_main (in dvgtkd)
==00:00:01:23.909 21109==    by 0x6C058C: main (in dvgtkd)

Why is the dtor failing every 2nd time? Can someone explain that?

What causes this message:
Source ID 7 was not found when attempting to remove it

Diez

Re: Memory leak in Pixbuf ctor/dtor?

On Tue, 04 Nov 2014 05:02:12 GMT, Diez wrote:

I get the following output:

MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
...

Well I did the same as you (I put messages in Pixbuf's ctor and dtor) and I just get one of each at time. You're getting twice.

But I'd to say that I'm currently using it on Windows and the gtkD is from 2012 (I don't remember the version and I'm not at home right now).

Just other thing:

In your cbtime() function, can you comment this line:

this.image.setFromPixbuf(this.pixbuf);

And see if you still getting the errors above or having the memory leaks?

Matheus.

Re: Memory leak in Pixbuf ctor/dtor?

Thanks for your reply.

In your cbtime() function, can you comment this line:

this.image.setFromPixbuf(this.pixbuf);

And see if you still getting the errors above or having the memory leaks?

No leak and no error now, but as expected also no image.

In the next test (with setFromPixbuf enabled again), although I added a 3rd image to the filenames array and the images switch nicely all 3, I get the assertion failure message every 2nd image switch and not every 3rd image switch (just to verify that it's not an issue with a certain image).

I'm out of clues now.

Diez

Re: Memory leak in Pixbuf ctor/dtor?

The GISOBJECT (object) failed error go's away when i change:

if (this.pixbuf) {
     delete this.pixbuf;
}

to:

if (this.pixbuf) {
     this.pixbuf.__dtor();
}

I still need to investigate as to whats going on when using delete.

Re: Memory leak in Pixbuf ctor/dtor?

On Tue, 04 Nov 2014 12:57:44 GMT, Diez wrote:

I'm out of clues now.

Tell me one thing: Are you using getPixbuf() somewhere in your code? If no, how are you displaying the image?

Matheus.

Pages: 1 2