GNOME Bugzilla – Bug 95606
Warning when removing child Gtk::VSeparator
Last modified: 2004-12-22 21:47:04 UTC
I get the following warning on my code: Gtk-CRITICAL **: file gtkcontainer.c: line 878 (gtk_container_remove): assertion `GTK_IS_CONTAINER (container)' failed after this occurs a number of times a crash occurs. The following is the smallest test case I can make to demonstrate the problem: #include <gtkmm.h> class TestWindow : public Gtk::Window { public: Gtk::VBox box; Gtk::HSeparator *sep; Gtk::Frame *frame; Gtk::Button button; TestWindow () { button.set_label( "Reset" ); button.signal_clicked().connect( SigC::slot( *this, &TestWindow::on_click ) ); box.pack_start( button ); add( box ); new_widget(); } void new_widget() { sep = new Gtk::HSeparator(); frame = new Gtk::Frame(); frame->add( *sep ); box.pack_start( *frame ); show_all(); } void on_click() { box.remove( *frame ); delete frame; delete sep; new_widget(); } }; int main( int argc, char *argv[] ) { Gtk::Main main_app( argc, argv ); main_app.run( *( new TestWindow() ) ); return 0; }
Compiler is g++-3.2, this is with a CVS pull from September 20.
Surely you can simplify this more. Maybe just removing one widget?
I tried to simplify this further but was unable to. It took me about 8 hours to reduce my program to this test case, and this is indicative of how fragile and specific the error situation is. You could probably remove button and box, these are primarily used to perform the removal action. However, you'd need some alternate means of triggering the removal action, like on a timer or close event. danielk suggested attempting to remove sep from frame before deletion, and this seems to work OK as a workaround.
Here is a simplified version of the test code. I noticed that the problem happens with a child VSeparator, but not with a child Button, so it doesn't seem to be a general lifetime problem.
Created attachment 11514 [details] test_child_separator.cc
Actually, it's an HSeparator, but I doubt that it makes any difference.
2002-10-21 Murray Cumming <murrayc@usa.net> * Gtk::Container_Class:destroy_callback(): dynamic_cast<> child widgets to Widget*, instead of Container*, of course. This seems to fix lots of lifetime bugs.