After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 606357 - Crash on exit if using canvas items derived from Goocanvas::ItemSimple
Crash on exit if using canvas items derived from Goocanvas::ItemSimple
Status: RESOLVED FIXED
Product: goocanvasmm
Classification: Other
Component: general
0.15.x
Other Linux
: Normal major
: ---
Assigned To: goocanvasmm-maint
goocanvasmm-maint
Depends on:
Blocks:
 
 
Reported: 2010-01-07 22:14 UTC by John McDonald
Modified: 2011-06-13 13:24 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
patch: Make 0 pointer conversion from Goocanvas::Canvas* to GooCanvas* work. (1.61 KB, patch)
2011-05-30 15:04 UTC, Kjell Ahlstedt
none Details | Review

Description John McDonald 2010-01-07 22:14:59 UTC
When I create a canvas item derived from GooCanvas::ItemSimple, my application crashes with a segmentation violation on exit (or whenever I try to clear the custom items canvas).  This crash does not occur if my object is derived from Goocanvas::Rect or Goocanvas::Ellipse.

I see exactly the same behavior in the custom_item example app from GooCanvas 0.14.0 (which I used as the pattern for my custom item).   The GooCanvas 0.15.1 source tarball does not appear to have an examples folder anymore.

The stack trace from the crash of the 0.14.0 custom_item example is as follows:
  • #0 Goocanvas::Item::set_canvas_vfunc
    from /usr/lib/libgoocanvasmm-0.1.so.5
  • #1 Goocanvas::Item_Class::set_canvas_vfunc_callback
    from /usr/lib/libgoocanvasmm-0.1.so.5
  • #2 goo_canvas_item_set_canvas
    from /usr/lib/libgoocanvas.so.3
  • #3 ??
    from /usr/lib/libgoocanvas.so.3
  • #4 Goocanvas::Item::set_parent_vfunc
    from /usr/lib/libgoocanvasmm-0.1.so.5
  • #5 Goocanvas::Item_Class::set_parent_vfunc_callback
    from /usr/lib/libgoocanvasmm-0.1.so.5
  • #6 goo_canvas_item_set_parent
    from /usr/lib/libgoocanvas.so.3
  • #7 ??
    from /usr/lib/libgoocanvas.so.3
  • #8 g_object_unref
    from /lib/libgobject-2.0.so.0
  • #9 ??
    from /usr/lib/libgoocanvas.so.3
  • #10 Gtk::Widget_Class::dispose_vfunc_callback
    from /usr/lib/libgtkmm-2.4.so.1
  • #11 g_object_run_dispose
    from /lib/libgobject-2.0.so.0
  • #12 gtk_object_destroy
    from /usr/lib/libgtk-x11-2.0.so.0
  • #13 Gtk::Object::_destroy_c_instance
    from /usr/lib/libgtkmm-2.4.so.1
  • #14 Gtk::Object::destroy_
    from /usr/lib/libgtkmm-2.4.so.1
  • #15 Goocanvas::Canvas::~Canvas
    from /usr/lib/libgoocanvasmm-0.1.so.5
  • #16 main
    at examplewindow.h line 26


As you can see, the above indicates that the seg fault is occurring in Goocanvas::Item::set_cancel_vfunc().   The source code for that function is as follows:

  void Goocanvas::Item::set_canvas_vfunc(Canvas* canvas) 
  {
    BaseClassType *const base = static_cast<BaseClassType*>(
        g_type_interface_peek_parent( // Get the parent interface of the interface (The original underlying C interface).
  g_type_interface_peek(G_OBJECT_GET_CLASS(gobject_), CppObjectType::get_type()) // Get the interface.
  )  );

    if(base && base->set_canvas)
      (*base->set_canvas)(gobj(),(canvas)->gobj());
  }

As you can see from this source code, if set_canvas_vfunc is called with a NULL canvas pointer, then a seg fault will occur at the last line.  This appears to be what is happening.  

If I extend my CustomItem class with its own set_canvas_vfunc() method which only calls Goocanvas::Item::set_canvas_item() if the Canvas* is non-NULL, my app does not crash.  While this *seems* to be an adequate workaround, it does not appear to be the way that other Goocanvas Items avoid this crash... Goocanvas::Rect, for example, does not have its own set_canvas_vfunc() method which filters out NULL canvas pointers. 

I don't know if there are any negative consequences for the above workaround.  I defer to those more familiar with the Goocanvas design for the answer to that.  But I did want to report what I'd found.  

Thanks in advance for any feedback you can provide.
Comment 1 Kjell Ahlstedt 2011-05-30 15:04:54 UTC
Created attachment 188889 [details] [review]
patch: Make 0 pointer conversion from Goocanvas::Canvas* to GooCanvas* work.

This patch fixes the bug, I believe. I've tested with the custom_item example
in goocanvasmm. The solution is to change the conversion from
Goocanvas::Canvas* to GooCanvas* that gmmproc uses when it generates .h and .cc
files out of .hg and .ccg files. The solution uses Glib::unwrap(canvas), which
tests if the argument is 0.

The changes in the generated source code are

diff goocanvasmm-org/item.cc goocanvasmm/item.cc
   1220c1220
   <         return (obj->get_canvas_vfunc())->gobj();
   ---
   >         return Glib::unwrap(obj->get_canvas_vfunc());
   2888c2888
   < goo_canvas_item_set_canvas(gobj(), (canvas)->gobj()); 
   ---
   > goo_canvas_item_set_canvas(gobj(), Glib::unwrap(canvas)); 
   3610c3610
   <     (*base->set_canvas)(gobj(),(canvas)->gobj());
   ---
   >     (*base->set_canvas)(gobj(),Glib::unwrap(canvas));

diff goocanvasmm-org/itemmodel.cc goocanvasmm/itemmodel.cc
   1779c1779
   <     return Glib::wrap((*base->create_item)(gobj(),(canvas)->gobj()), false);
   ---
   >     return Glib::wrap((*base->create_item)(gobj(),Glib::unwrap(canvas)), false);

I'm not very familiar with the goocanvas and goocanvasmm modules, but I don't
see any possible drawback with this solution. Perhaps someone more familiar
with the modules can confirm.
Comment 2 Kjell Ahlstedt 2011-06-12 16:39:07 UTC
I have pushed the patch (with a small difference in ChangeLog). No one has
objected to comment 1, and I'm convinced that this fix is correct.

This bug has inspired the gtkmm-list message
http://mail.gnome.org/archives/gtkmm-list/2011-June/msg00011.html
"Are vtables of interfaces always correctly initialized?"
Comment 3 Murray Cumming 2011-06-13 13:24:11 UTC
It looks good. Thanks.