GNOME Bugzilla – Bug 104194
A window with an option menu seg-faults when closed.
Last modified: 2006-04-26 09:46:42 UTC
I have a simple program to illustrate my problem. Run the program, close the window and behold these errors: ~/code/gtkbonus/src 7> ./a.out (a.out:5621): GLib-GObject-WARNING **: instance with invalid (NULL) class pointer (a.out:5621): GLib-GObject-CRITICAL **: file gsignal.c: line 2056 (g_signal_handlers_destroy): assertion `G_TYPE_CHECK_INSTANCE (instance)' failed (a.out:5621): GLib-GObject-WARNING **: instance of invalid non-instantiatable type `gint64' (a.out:5621): GLib-GObject-CRITICAL **: file gsignal.c: line 2056 (g_signal_handlers_destroy): assertion `G_TYPE_CHECK_INSTANCE (instance)' failed Segmentation fault And here is the program that exhibits this error. If you change the two lines that pack the menu items into the menu by using the push_back to instead using the append, it no longer happens. #include <gtkmm/optionmenu.h> #include <gtkmm/menu.h> #include <gtkmm/window.h> #include <gtkmm/main.h> class test_window : public Gtk::Window { Gtk::OptionMenu some_menu; Gtk::MenuItem menu_one, menu_two; Gtk::Menu the_menu; public: test_window(); }; test_window::test_window() : menu_one("One"), menu_two("Two") { Gtk::Menu_Helpers::MenuList& menulist=the_menu.items(); menulist.push_back(menu_one); menulist.push_back(menu_two); // the_menu.append(menu_one); // the_menu.append(menu_two); some_menu.set_menu(the_menu); add(some_menu); show_all(); } int main(int argc, char *argv[]) { Gtk::Main main_runner(argc, argv); test_window foo; main_runner.run(foo); return(0); } It has been suggested that this bug is actually bug #78578. The differences, though are that this bug happens with GCC 3.2, that bug confirmed that it did not occur with that version of GCC, and also I do not find any error messages in that bug's comments. Finally, that one deals with a constructor, this one happens during destruction. Here is a backtrace:
+ Trace 33029
Thanks. Fixed in cvs. 2003-01-24 Murray Cumming <murrayc@usa.net> * gtk/gtkmm/menu_elems.cc: Element::Element(MenuItem): Use the Glib::RefPtr<> constructor explicitly, for clarity, and do the necessary extra ref - fixes lifetime bug 104194
I'm still getting errors related to this bug. If I've done things correctly, then I'm using the latest CVS of 2.2.x. I believe I am using the latest CVS because I was able to get my example above to compile and run without any errors. The errors re-manifested themselves in my application, however. I investigated, and it appears that if you rearrange the order of the Gtk::OptionMenu, Gtk::Menu, and Gtk::MenuItem lines in the example, it will seg-fault (without any error messages). Specifically, I've got MenuItem, then Menu, then OptionMenu. I'm not sure if this is supposed to be a bug, or if the user is supposed to ensure that these items are constructed in the correct order, so that you don't have an OptionMenu being destructed before it's items are gone. At any rate, I ran the example through valgrind, and interestingly enough, when I do that the error lines from above are printed out (along with valgrinds info on what's going on). Here is some of what valgrind has to say (hopefully the important parts): ==1376== Invalid read of size 4 ==1376== at 0x408186B9: g_type_check_instance (in /usr/lib/libgobject-2.0.so.0.200.0) ==1376== Address 0x41DC5334 is 0 bytes inside a block of size 100 free'd ==1376== at 0x4003DD29: free (in /usr/lib/valgrind/valgrind.so) ==1376== by 0x4084E295: g_free (in /usr/lib/libglib-2.0.so.0.200.0) ==1376== by 0x41D42F9C: ??? ==1376== by 0xE0107000: ??? (a.out:1376): GLib-GObject-WARNING **: instance with invalid (NULL) class pointer (a.out:1376): GLib-GObject-CRITICAL **: file gsignal.c: line 2300 (g_signal_handlers_disconnect_matched): assertion `G_TYPE_CHECK_INSTANCE (instance)' failed ==1376== ==1376== Invalid read of size 4 ==1376== at 0x4058A1FE: gtk_option_menu_detacher (in /usr/lib/libgtk-x11-2.0.so.0.200.0) ==1376== by 0x40812EBB: g_cclosure_marshal_VOID__VOID (in /usr/lib/libgobject-2.0.so.0.200.0) ==1376== by 0x15B: ??? ==1376== Address 0x41DC5334 is 0 bytes inside a block of size 100 free'd ==1376== at 0x4003DD29: free (in /usr/lib/valgrind/valgrind.so) ==1376== by 0x4084E295: g_free (in /usr/lib/libglib-2.0.so.0.200.0) ==1376== by 0x41D42F9C: ??? ==1376== by 0xE0107000: ??? ==1376== ==1376== Invalid read of size 4 ==1376== at 0x40818420: g_type_check_instance_is_a (in /usr/lib/libgobject-2.0.so.0.200.0) ==1376== by 0x40812EBB: g_cclosure_marshal_VOID__VOID (in /usr/lib/libgobject-2.0.so.0.200.0) ==1376== by 0x15B: ??? ==1376== Address 0x41DC5334 is 0 bytes inside a block of size 100 free'd ==1376== at 0x4003DD29: free (in /usr/lib/valgrind/valgrind.so) ==1376== by 0x4084E295: g_free (in /usr/lib/libglib-2.0.so.0.200.0) ==1376== by 0x41D42F9C: ??? ==1376== by 0xE0107000: ??? (a.out:1376): Gtk-CRITICAL **: file gtkoptionmenu.c: line 247 (gtk_option_menu_detacher): assertion `GTK_IS_OPTION_MENU (widget)' failed ==1376== ==1376== Invalid read of size 4 ==1376== at 0x4058B19C: gtk_option_menu_item_destroy_cb (in /usr/lib/libgtk-x11-2.0.so.0.200.0) ==1376== by 0xB33: ??? ==1376== Address 0x41DC5378 is 68 bytes inside a block of size 100 free'd ==1376== at 0x4003DD29: free (in /usr/lib/valgrind/valgrind.so) ==1376== by 0x4084E295: g_free (in /usr/lib/libglib-2.0.so.0.200.0) ==1376== by 0x41D42F9C: ??? ==1376== by 0xE0107000: ???
Please _attach_ a test case. We can do nothing without that.
Created attachment 13896 [details] Current seg-fault test case.
Created attachment 13924 [details] [review] test2.cc - simplified test case
Created attachment 13925 [details] [review] test2.cc - simplified test case
Here is a simplified test case (test2.cc - sorry for submitting it twice) that just segfaults without warnings on exit.
Created attachment 14595 [details] Menu destruction crash testcase
The soultion would be the attempt to force menu to work like Container widget with "manage" feature. So, if you are using submenu as in-class member, Menu won't attempt to destroy it, and if you are creating submenu with manage(), it should be destroyed automatically. Some time ago, GtkMenu didn't destroy children, so, we haven't met that segfault. Now, it seems, GTK team fixed that, and caused underwater boulders to raise up.
Gtk::Menu is a container and should act like a container. Yes, it should manage it's widgets when you use Gtk::manage(), but not when you don't.
I believe I have fixed this now: 2003-05-06 Murray Cumming <murrayc@usa.net> * gtk/src/optionmenu.[hg|ccg]: Implemented a custom destructor which calls remove_menu(), to prevent the menu (set with set_menu()), from remembering a dead OptionMenu. See the comment in the destructor for more details. "Current seg-fault test case." no longer segfaults.
I thought the issue was fixed completelly Menu test case still crashes on gtkmm ver. 2.4.7. Should I submit a separate bug or just repoen this one?
I can't reproduce this with gtkmm 2.8 (2.8.5, for instance), with the "Current seg-fault test case." in #4. Note that if I find a bug, I'm unlikely to fix it in gtkmm 2.4, unless you have a very good reason for using it. I'm doing some maintainance of gtkmm 2.6, because it's needed for embedded work until the cairo floating-point issues are dealt with.
I can reproduce it with your test case in #8. But this is nothing to do with OptionMenu, so I've opened a new bug for it: http://bugzilla.gnome.org/show_bug.cgi?id=339791