FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Memory bug in gtkD?
Goto page 1, 2  Next
 
Post new topic   Reply to topic     Forum Index -> gtkD
View previous topic :: View next topic  
Author Message
TiMBuS



Joined: 21 Dec 2007
Posts: 11

PostPosted: Wed Mar 26, 2008 7:46 pm    Post subject: Memory bug in gtkD? Reply with quote

Hey guys.
I think I may have found a bug in gtkD, but I'm not 100% sure if its not actually my fault.

I wrote an application with gtkD with glade. The main() function is not much more than this:
Code:
glXml = new Glade(gladeFile);
new FrontWnd;
GtkD.main();

The FrontWnd hooks up all the handlers and etc when it is created.

It all normally runs fine, but I was worrying to myself about if the garbage collector might actually clean up 'FrontWnd' since technically there are no solid references to it. So, as a simple test I added "std.gc.fullCollect();" after "new FrontWnd" is called. The program still runs fine, and FrontWnd's destructor is never called so it all seems ok. But then I click on a combobox and the program segfaults. I've traced the error down to a line:

Code:

private void onChangeMenu(ComboBox cb){
   TreeModel model = cb.getModel(); //Here.
   ...

it seems calling getModel on the passed param causes the segmentation fault, but this only happens if I run a fullCollect before calling GtkD.main();
Perhaps something in gtkD is getting cleaned up when it shouldn't? I've also noticed that after fiddling with the interface for a few seconds, all of the event callbacks just stop working. They never get called when they should.
Is this my doing, or a problem in gtkD?
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Thu Mar 27, 2008 4:35 pm    Post subject: Reply with quote

Normally the pointers to the gtk structs get added as a root to the garbage collector.

How does FrontWnd hook up the handlers?
Back to top
View user's profile Send private message
TiMBuS



Joined: 21 Dec 2007
Posts: 11

PostPosted: Thu Mar 27, 2008 9:37 pm    Post subject: Reply with quote

Mike Wey wrote:
Normally the pointers to the gtk structs get added as a root to the garbage collector.

How does FrontWnd hook up the handlers?


Code:
(cast(ComboBox)glXml.getWidget("Menu")).addOnChanged(&onChangeMenu);

Perhaps I need to store the widgets I get from the glade object?
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Sat Mar 29, 2008 6:34 am    Post subject: Reply with quote

The GtkD class instance is added as a pionter to the data when connecting the signals. I don't know where gtk stores this data, it might be someware the Garbage Collector can't find it. whitch leeds to it collecting the GtkD classes.

Storing the Widgets should stop the Garbage Collector from collecting them.
Back to top
View user's profile Send private message
TiMBuS



Joined: 21 Dec 2007
Posts: 11

PostPosted: Sat Mar 29, 2008 7:54 pm    Post subject: Reply with quote

Mike Wey wrote:
The GtkD class instance is added as a pionter to the data when connecting the signals. I don't know where gtk stores this data, it might be someware the Garbage Collector can't find it. whitch leeds to it collecting the GtkD classes.

Storing the Widgets should stop the Garbage Collector from collecting them.


Hmm, this should probably be handled by the glade object. You shouldn't need to store glade pointers, they're usually just called then thrown away again.
Oh well, for now I'll just keep an associative array of widgets and it should hopefully fix the problem.

EDIT: It did fix it.
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Sun Mar 30, 2008 8:27 am    Post subject: Reply with quote

Quote:
Normally the pointers to the gtk structs get added as a root to the garbage collector.


Did some more searching and actually a pointer to the GtkD class gets added as a root for the garbage collector and the pointer is stored in the associated gtk struct. So the Garbage Collector shouldn't collect the GtkD classes.
Back to top
View user's profile Send private message
TiMBuS



Joined: 21 Dec 2007
Posts: 11

PostPosted: Mon Mar 31, 2008 6:51 pm    Post subject: Reply with quote

Mike Wey wrote:
Quote:
Normally the pointers to the gtk structs get added as a root to the garbage collector.


Did some more searching and actually a pointer to the GtkD class gets added as a root for the garbage collector and the pointer is stored in the associated gtk struct. So the Garbage Collector shouldn't collect the GtkD classes.


So, why are the objects being collected? Is there some kind of explicit delete going on? Or perhaps addroot isn't being used properly?
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Tue Apr 01, 2008 3:36 pm    Post subject: Reply with quote

I can't think of any explicit deleting someware, i also haven't been able to reproduce this. I tried hooking up 50 buttons in the same way FrontWnd does it and calling fullCollect before GtkD.Main(). hasn't led to any problems yet.

Might i ask wicht versions of the compiler and phobos/tango you are using?
Back to top
View user's profile Send private message
TiMBuS



Joined: 21 Dec 2007
Posts: 11

PostPosted: Wed Apr 02, 2008 5:45 am    Post subject: Reply with quote

I'm using DMD 1.028, and the latest phobos v1 that comes with it.
I also have the latest preview release of gtkD.

Are you using a glade file to try and reproduce these results?
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Wed Apr 02, 2008 12:27 pm    Post subject: Reply with quote

Yes i am using glade, and i'm changing the text on the buttons to see if the reference that gets passed to function is still valid.
Back to top
View user's profile Send private message
TiMBuS



Joined: 21 Dec 2007
Posts: 11

PostPosted: Thu Apr 03, 2008 3:51 am    Post subject: Reply with quote

I've been looking into it a bit more.
Oddly enough buttons work. As far as I can see, only combo boxes are having this problem. I checked to see if it was calling 'getModel' that caused the error but it appears that calling anything on the combobox object causes a segfault.

Maybe there is something wrong with the way comboboxes register events? specifically, addOnChanged?
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Fri Apr 04, 2008 2:04 pm    Post subject: Reply with quote

I haven't had any luck reproducing this with comboboxes.
Back to top
View user's profile Send private message
okibi



Joined: 04 Jan 2007
Posts: 170

PostPosted: Sat Apr 05, 2008 7:21 am    Post subject: Reply with quote

I couldn't reproduce this with comboboxes either.

However, if I create an associative array of textbuffers (such as TextBuffer[char[]]) and connect the addOnChanged function to an outside function to handle it, I can get a segfault every now and then.

I'll continue to look into this issue.
Back to top
View user's profile Send private message
TiMBuS



Joined: 21 Dec 2007
Posts: 11

PostPosted: Mon Apr 14, 2008 5:02 am    Post subject: Reply with quote

Okay I've been away a bit and focusing on some Perl work so I haven't really looked further into this.

So just a few minutes ago I thought I should have a more in-depth look and maybe post a simple example to recreate the error (which I may still do). So, I was stripping down the program so I could post a quick example, when I noticed this in the constructor of FrontWnd:

Code:
(cast(ComboBox)glXml.getWidget("Menu")).addOnChanged(&onChangeMenu);
//Other stuff...
ComboBox cb = cast(ComboBox)glXml.getWidget("Menu");
fillComboBox(cb, ["foo","bar","baz"]);
cb.setActive(0);


For some reason it seemed significant, so I changed it into this:
Code:
//(cast(ComboBox)glXml.getWidget("Menu")).addOnChanged(&onChangeMenu);
//Other stuff...
ComboBox cb = cast(ComboBox)glXml.getWidget("Menu");
cb.addOnChanged(&onChangeMenu);
fillComboBox(cb, ["foo","bar","baz"]);
cb.setActive(0);

No segfault.

I also just tried this:
Code:
(cast(ComboBox)glXml.getWidget("Menu")).addOnChanged(&onChangeMenu);
//Other stuff...
ComboBox cb = cast(ComboBox)glXml.getWidget("Menu");
cb.addOnPopup(&doNothing);
fillComboBox(cb, ["foo","bar","baz"]);
cb.setActive(0);

doNothing() just writes the passed combobox's 'getActive' function to the console. doNothing works without error, but changing the menu option gives a segfault.
Reversing the positions of addOnChanged and addOnPopup makes changing the menu option work, but triggering the popup gives a segfault.
So I guess it's something to do with creating two references to the same glade object in the same scope? It somehow makes the first reference invalid?
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Wed Apr 16, 2008 2:28 pm    Post subject: Reply with quote

I was working on this a bit more today, and i'm now able to reproduce the segfault this time. The first time i was doing something along the lines of the second example you posted.

Here is the code i used this time:
Code:
module glade.textGlade;

import glade.Glade;
import gtk.GtkD;
import gtk.Window;
import gtk.Widget;
import gtk.ComboBox;
import gtk.TreeIter;
import gtk.ListStore;
import gtk.CellRenderer;
import gtk.CellRendererText;

version(Tango){
    import tango.stdc.stdlib : exit;
    import tango.io.Stdout;
    import tango.text.Util;
   import tango.core.Memory;

    void writefln( string frm, ... ){
        string frm2 = substitute( frm, "%s", "{}" );
        Stdout( Stdout.layout.convert( _arguments, _argptr, frm2 )).newline;
    }
}
else{
    import std.stdio;
    import std.c.process;
   import std.gc;
}

class Test
{
   this()
   {
      Glade g = new Glade("gladeTest.glade");

      (cast(Window)g.getWidget("window1")).setTitle("This is a glade window");

      (cast(ComboBox)g.getWidget("combobox1")).addOnChanged( &test );

      ListStore listStore = new ListStore([GType.STRING]);



      TreeIter iterTop = listStore.createIter();

      listStore.setValue(iterTop,0,"Test");


      listStore.append(iterTop);

      listStore.setValue(iterTop,0,"Test");



      (cast(ComboBox)g.getWidget("combobox1")).setModel(listStore);
      (cast(ComboBox)g.getWidget("combobox1")).setWrapWidth(1);

      CellRenderer renderer = new CellRendererText();

      (cast(ComboBox)g.getWidget("combobox1")).packStart(renderer, true);

      (cast(ComboBox)g.getWidget("combobox1")).addAttribute(renderer, "text",0);

      (cast(Window)g.getWidget("window1")).addOnHide( delegate void(Widget aux){ exit(0); } );
      (cast(Window)g.getWidget("window1")).showAll();
   }

   void test(ComboBox cbx)
   {
      auto model = cbx.getModel();
   }
}

int main(string[] args)
{
   GtkD.init(args);
   new Test;

   version(Tango)
      GC.collect();
   else
      fullCollect();      

   GtkD.main();
   return 0;

}
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> gtkD All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group