From: Kris Thielemans <kris.f.thielemans@gm...>  20140621 22:32:25

> From: William Fulton, Sent: 18 June 2014 07:39 > On 15/06/14 17:29, Kris Thielemans wrote: > >>From William Fulton, Sent: 10 June 2014 19:14 > >> On 08/06/14 12:25, Kris Thielemans wrote: > >>> Hi > >>> > >>> I'm trying to get the matlab module to work and have a very strange > >> problem. In MATLAB::classHandler, we go through the list of baseclasses > > to > >> output those to matlab. The code goes as follows > >>> > >>> List *baselist = Getattr(n, "bases"); > >>> if(baselist){ > >>> // Loop over base classes > >>> for (Iterator b = First(baselist); b.item; b = Next(b)) { > >>> // Get base class name, possibly ignore > >>> String *bname = Getattr(b.item, "sym:name"); > >>> // Etc > >>> } > >>> > >>> This works nicely most of the time, but for 2 classes in my project, the > >> resulting bname is set to "destructor" which comes from nowhere (I assure > > you > >> I have no destructor class), even though the "name" attribute is correct > > (in my > >> case for instance "stir::ProjData"). I can't see anything special for > > these classes. > >>> > >>> Any idea where this comes from or how I can debug this? > >> > >> Sounds like a bug somewhere. Get a short testcase and look at the output > >> of debugcsymbols and debugsymbols. Also debugmodule 1 and see if > >> anything goes haywire as you increase upwards from 1. > >> > > > > thanks William > > > > I've boiled this down to a very short testcase (see below). This happens > > when using a forwarddeclaration for a class. The problem shows up at stage > > 4 (using the debugmodule) switch, stage 3 is ok. I've checked that the > > printout of debugmodule when using python or octave output is fine, so it > > is indeed a bug in the matlab module. I have no idea how to find out where > > this happens. > > > > > > Here's the example interface file > >  > > %module swigtest > > %{ > > %} > > %inline %{ > > > > class A; > > > > class B > > { > > public: > > B(const A&) {} > > }; > > > > class A > > {}; > > > > class A2: public A > > { > > A2() : A() {} > > }; > > %} > >  > > > > When I run this with the matlab module, e.g. > > > > swig matlab c++ debugmodule 4 o wrap.cpp swigtest.i > > > > the output is like this > > > > +++ classforward  > >  sym:name  "A" > >  name  "A" > >  kind  "class" > >  sym:weak  "1" > >  sym:symtab  0x7f674db2f8f0 > >  sym:overname  "__SWIG_0" > >  > > +++ class  > >  classtype  "B" > >  name  "B" > >  sym:symtab  0x7f674db2f8f0 > >  symtab  0x7f674da94230 > >  allows_typedef  "1" > >  typepass:visit  "1" > >  allocate:visit  "1" > >  kind  "class" > >  sym:name  "B" > >  allocate:has_constructor  "1" > >  allocate:public_constructor  "1" > >  allocate:copy_constructor  "1" > >  allocate:default_destructor  "1" > >  has_destructor  "1" > >  allocate:destructor  "1" > >  has_constructor  "1" > >  classtypeobj  "B" > >  module  0x7f674da93e90 > >  sym:overname  "__SWIG_0" > >  typescope  0x7f674da95410 > > > > +++ access  > >  kind  "public" > >  > > +++ constructor  > >  name  "B" > >  ismember  "1" > >  sym:symtab  0x7f674da94230 > >  sym:name  "B" > >  view  "constructorDeclaration" > >  wrap:parms  A const & > >  decl  "f(r.q(const).A)." > >  tmap:out  "_out = SWIG_NewPointerObj(SWIG_as_voidptr(result), > > SWIGTYPE_p_B, 1  0 );" > >  access  "public" > >  parms  A const & > >  wrap:action  "result = (B *)new B((A const &)*arg1);" > >  wrap:name  "_wrap_new_B" > >  code  "{}" > >  tmap:out:noblock  "1" > >  sym:overname  "__SWIG_0" > >  feature:new  "1" > >  > > +++ access  > >  kind  "public" > >  > > +++ destructor  > >  name  "~B" > >  sym:symtab  0x7f674da94230 > >  view  "destructorDeclaration" > >  sym:name  "~B" > >  wrap:parms  B *self > >  decl  "f()." > >  tmap:out  "_out = (mxArray*)0;" > >  access  "public" > >  wrap:action  "delete arg1;" > >  wrap:name  "_wrap_delete_B" > >  tmap:out:noblock  "1" > >  sym:overname  "__SWIG_0" > >  > > +++ class  > >  classtype  "A" > >  name  "A" > >  sym:symtab  0x7f674db2f8f0 > >  symtab  0x7f674da947f0 > >  allows_typedef  "1" > >  typepass:visit  "1" > >  allocate:visit  "1" > >  kind  "class" > >  sym:name  "destructor" > >  allocate:default_constructor  "1" > >  allocate:copy_constructor  "1" > >  allocate:default_destructor  "1" > >  has_default_constructor  "1" > >  has_destructor  "1" > >  allocate:destructor  "1" > >  has_constructor  "1" > >  classtypeobj  "A" > >  module  0x7f674da93e90 > >  sym:overname  "__SWIG_0" > >  typescope  0x7f674da95650 > > > > > > Etc > > > > where you see that sym:name of class A is set to "destructor" (in pass 3 > > it's still "A"). > > any suggestions? > > > I'd guess either memory corruption or possibly some other bug where the > sym:name is explicitly set. If you've tried the memory debugging > techniques I posted a few days ago on 10 June without any luck, I'd > liberally sprinkle calls to Swig_print passing the class node in code > that handles the class to try and see when it goes wrong. > Thanks William, #defining DOH_DEBUG_MEMORY_POOLS did the trick. It threw up an assert(!DOH_object_already_deleted). It turned out that in MATLAB::classHandler we were Deleting a String obtained via GetAttr, which is incorrect (as that meant we were deleting the attribute). After fixing that, this problem disappeared. Great! Joel, I've committed this on my github fork. Kris 