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 642203 - Gtk::Builder & sigc::bind interaction around actions causes crash in dtor
Gtk::Builder & sigc::bind interaction around actions causes crash in dtor
Status: RESOLVED DUPLICATE of bug 564005
Product: gtkmm
Classification: Bindings
Component: general
2.20.x
Other Linux
: Normal normal
: ---
Assigned To: gtkmm-forge
gtkmm-forge
Depends on:
Blocks:
 
 
Reported: 2011-02-13 00:47 UTC by Chris MacGregor
Modified: 2011-03-30 09:39 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
testcase; see description for compile command line & valgrind options (6.75 KB, text/x-c++src)
2011-02-13 00:47 UTC, Chris MacGregor
Details

Description Chris MacGregor 2011-02-13 00:47:50 UTC
Created attachment 180752 [details]
testcase; see description for compile command line & valgrind options

The circumstances are rather specific, so please bear with me here:

Binding a RefPtr <ToggleAction> to the signal handler for the SlotActivate for an action in an actiongroup which gets added to a widget created by Gtk::Builder will result in a crash in the dtor for the containing widget.

More verbosely:

1. I create a Gtk::ToggleAction and add it to a Gtk::ActionGroup, using sigc::bind to arrange to pass the RefPtr for the action as an argument to the handler, like so:

        actiongp->add (action, sigc::bind <const char *,
                       Glib::RefPtr <Gtk::ToggleAction> >
                       (sigc::mem_fun (*this, actionfunc), name, action));

2. I use Gtk::UIManager to create a menubar referencing this action, and add that menubar to a widget created by Gtk::Builder.

3. I crash in the dtor for the top-level widget, apparently because (according to Valgrind) sigc is reading memory inside a block it had previously freed.  See valgrind output quoted below for the attached testcase.

4. If I remove the menubar from the widget before reaching the end of the explicit code for my dtor, then all is well (as long as I don't delete the menubar).

See attached testcase for details.  It's fairly short (188 lines).

Valgrind 3.6.0 on Ubuntu 10.10 (I love Valgrind) says:

==27508== Invalid read of size 8
==27508==    at 0x68DD050: sigc::internal::slot_rep::disconnect() (in /usr/lib/libsigc-2.0.so.0.0.0)
==27508==    by 0x68DD0AE: sigc::internal::slot_rep::notify(void*) (in /usr/lib/libsigc-2.0.so.0.0.0)
==27508==    by 0x68DCB9E: sigc::internal::trackable_callback_list::~trackable_callback_list() (in /usr/lib/libsigc-2.0.so.0.0.0)
==27508==    by 0x68DCC80: sigc::trackable::notify_callbacks() (in /usr/lib/libsigc-2.0.so.0.0.0)
==27508==    by 0x407145: MyWin::~MyWin() (problem-110212.cpp:172)
==27508==    by 0x405DEE: main (problem-110212.cpp:185)
==27508==  Address 0xce1fe88 is 40 bytes inside a block of size 112 free'd
==27508==    at 0x4C27A83: operator delete(void*) (vg_replace_malloc.c:387)
==27508==    by 0x649CD09: Glib::SignalProxyConnectionNode::destroy_notify_handler(void*, _GClosure*) (in /usr/lib/libglibmm-2.4.so.1.3.0)
==27508==    by 0x85005AA: g_closure_unref (in /usr/lib/libgobject-2.0.so.0.2600.0)
==27508==    by 0x85156CC: g_signal_handlers_destroy (in /usr/lib/libgobject-2.0.so.0.2600.0)
==27508==    by 0x850282C: ??? (in /usr/lib/libgobject-2.0.so.0.2600.0)
==27508==    by 0x8502999: g_object_unref (in /usr/lib/libgobject-2.0.so.0.2600.0)
==27508==    by 0x4071E2: Glib::RefPtr<Gtk::ToggleAction>::~RefPtr() (refptr.h:184)
==27508==    by 0x4060EB: sigc::bound_argument<Glib::RefPtr<Gtk::ToggleAction> >::~bound_argument() (bound_argument.h:51)
==27508==    by 0x406109: sigc::bind_functor<-1, sigc::bound_mem_functor2<void, MyWin, char const*, Glib::RefPtr<Gtk::ToggleAction> >, char const*, Glib::RefPtr<Gtk::ToggleAction>, sigc::nil, sigc::nil, sigc::nil, sigc::nil, sigc::nil>::~bind_functor() (bind.h:136)
==27508==    by 0x407A33: sigc::internal::typed_slot_rep<sigc::bind_functor<-1, sigc::bound_mem_functor2<void, MyWin, char const*, Glib::RefPtr<Gtk::ToggleAction> >, char const*, Glib::RefPtr<Gtk::ToggleAction>, sigc::nil, sigc::nil, sigc::nil, sigc::nil, sigc::nil> >::destroy(void*) (slot.h:61)
==27508==    by 0x68DD0A6: sigc::internal::slot_rep::notify(void*) (in /usr/lib/libsigc-2.0.so.0.0.0)
==27508==    by 0x68DCB9E: sigc::internal::trackable_callback_list::~trackable_callback_list() (in /usr/lib/libsigc-2.0.so.0.0.0)
==27508==    by 0x68DCC80: sigc::trackable::notify_callbacks() (in /usr/lib/libsigc-2.0.so.0.0.0)
==27508==    by 0x407145: MyWin::~MyWin() (problem-110212.cpp:172)
==27508==    by 0x405DEE: main (problem-110212.cpp:185)

To compile & run under valgrind:

g++ -ggdb3 -pthread -o problem-110212 problem-110212.cpp `pkg-config --cflags --libs gtkmm-2.4` && valgrind --read-var-info=yes --tool=memcheck --num-callers=50 ./problem-110212
Comment 1 Kjell Ahlstedt 2011-03-22 18:15:02 UTC
I suggest that this bug is made a duplicate of bug 564005.

Copied from bug 564005 comment 8:

  What makes the test case special is that 'action' has two roles:
  1. It's the receiver of signal_activate.
  2. It's bound to a slot which is connected to the signal.

In this case the trouble is caused by the double use of 'action' in

  actiongp->add (action, sigc::bind <const char *,
                 Glib::RefPtr <Gtk::ToggleAction> >
                 (sigc::mem_fun (*this, actionfunc), name, action));

If another ToggleAction instance, or no ToggleAction instance, is bound then
valgrind does not complain.

When the statement
  top_vbox->remove (*menubar);
in MyWin::~MyWin() is activated, valgrind does not report errors, but gdb shows
that menubar is not deleted. (MenuBar::~MenuBar is not called.) Strange though
that valgrind does not report more leaked memory in this case.
Comment 2 Chris MacGregor 2011-03-27 01:13:08 UTC
(In reply to comment #1)
> I suggest that this bug is made a duplicate of bug 564005.

Agreed, it does appear to be the same issue.
Comment 3 Kjell Ahlstedt 2011-03-30 08:34:27 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > I suggest that this bug is made a duplicate of bug 564005.
> 
> Agreed, it does appear to be the same issue.

Can't you as the reporter of this bug mark it as a duplicate yourself?

Concerning your question in bug 564005 comment 9 (Any hope of a fix?), my guess
is that it can take a long long time. There is also the glibmm bug 154498,
filed in the year 2004, probably describing the same error. The error is most
probably in libsigc++. It is a fairly small module, but it's tricky.
Comment 4 Murray Cumming 2011-03-30 09:39:35 UTC

*** This bug has been marked as a duplicate of bug 564005 ***