GNOME Bugzilla – Bug 660347
The Find ID feature crashes
Last modified: 2013-10-27 19:37:20 UTC
Using the Find button next to foreign key IDs (such as the Publisher ID in the Albums table in the Music example), causes a a crash after choosing the found record. Here is the gdb backtrace at this warning " Glib::wrap_create_new_wrapper: Attempted to create a 2nd C++ wrapper for a C instance whose C++ wrapper has been deleted. " just before the crash. There is no valgrind error before this. Breakpoint 1, g_log (log_domain=0x15aafb6 "glibmm", log_level=G_LOG_LEVEL_WARNING, format=0x15aafc0 "Glib::wrap_create_new_wrapper: Attempted to create a 2nd C++ wrapper for a C instance whose C++ wrapper has been deleted.") at gmessages.c:590 590 va_start (args, format); (gdb) bt
+ Trace 228619
If I call remove_all_columns() in the DbAddDel descructor, I get this backtrace at the first warning: Breakpoint 1, g_log (log_domain=0x15aafb6 "glibmm", log_level=G_LOG_LEVEL_WARNING, format=0x15aafc0 "Glib::wrap_create_new_wrapper: Attempted to create a 2nd C++ wrapper for a C instance whose C++ wrapper has been deleted.") at gmessages.c:590 590 va_start (args, format); (gdb) bt
+ Trace 228620
+ Trace 228621
If I do remove_all_columns in the Gtk::TreeView destructor, I get this warning (glom:763): Gtk-CRITICAL **: gtk_tree_view_get_cell_area: assertion `column == NULL || GTK_IS_TREE_VIEW_COLUMN (column)' failed with this backtrace at at that point: Breakpoint 1, g_log (log_domain=0x1a9936f "Gtk", log_level=G_LOG_LEVEL_CRITICAL, format=0x233755c "%s: assertion `%s' failed") at gmessages.c:590 590 va_start (args, format); (gdb) bt
+ Trace 228622
Created attachment 197731 [details] [review] #include <giomm/file.h> This patch adds a simpler use of the dialog to tests/test_selfhosting_new_from_example. Just do make ./tests/test_selfhosting_new_from_example to build only that test. This is not suitable for pushing because it requires user interaction in the test. It shows the same problem.
Created attachment 197739 [details] [review] test_dialog_choose_id3.patch This patch rips out most of the dialog and makes the test case non-interactive, via a 2-second timeout to cancel the dialog. It still shows the problem.
This commit works around the crash in Glom, though it would be good to fix it properly because it will probably happen somewhere else. http://git.gnome.org/browse/glom/commit/?id=5cf223201ece3534ab177e7eaaa75322542e8bec
(In reply to comment #2) > If I call remove_all_columns() in the DbAddDel descructor, I get this backtrace > at the first warning: Note that remove_all_columns() call in DbAddDel destructor calls in fact DbAddDel::remove_all_columns() which has nothing in common with Gtk::TreeView::remove_all_columns(). (In reply to comment #3) > If I do remove_all_columns in the Gtk::TreeView destructor, I get this warning > > (glom:763): Gtk-CRITICAL **: gtk_tree_view_get_cell_area: assertion `column == > NULL || GTK_IS_TREE_VIEW_COLUMN (column)' failed > > with this backtrace at at that point: And this is IMO a bug in GtkTreeViewAccessible: static void columns_changed (GtkTreeView *tree_view) improperly detects a remove of column as a some kind of move and then refers to removed column, which have ref_count 0 at this point. This warning does not appear if you remove columns from the end. That is - if below code is used in DbAddDel destructor no warning shows: (It is similar to Gtk::TreeView::remove_all_columns, but I used reverse iterators here.) typedef std::vector<Gtk::TreeView::Column*> type_vecViewColumns; type_vecViewColumns vecViewColumns (m_TreeView.get_columns()); for (type_vecViewColumns::reverse_iterator iter (vecViewColumns.rbegin ()), columns_end (vecViewColumns.rend ()); iter != columns_end; ++iter) { Gtk::TreeView::Column* pViewColumn (*iter); if(pViewColumn) { m_TreeView.remove_column(*pViewColumn); } } I wonder if this could be reproducible with C example.
Closing because we now have a workaround, and the real problem is being dealt with in GTK+ bug #661058 .
Bug #661058 was apparently fixed, but if I remove the workaround, I still see a crash. Here is the backtrace: Program received signal SIGSEGV, Segmentation fault. 0x08295cb6 in Gtk::Widget::gobj (this=0x0) at /opt/gnome30/include/gtkmm-3.0/gtkmm/widget.h:289 289 GtkWidget* gobj() { return reinterpret_cast<GtkWidget*>(gobject_); } (gdb) bt
+ Trace 229185
This time I see these warnings: glibmm-WARNING **: Glib::wrap_create_new_wrapper: Attempted to create a 2nd C++ wrapper for a C instance whose C++ wrapper has been deleted. glibmm-WARNING **: Failed to wrap object of type 'gtkmm__GtkTreeView'. Hint: this error is commonly caused by failing to call a library init() function.
And this is the valgrind output at that point: ==27575== Invalid read of size 4 ==27575== at 0x8295CB6: Gtk::Widget::gobj() (widget.h:289) ==27575== by 0x5059E23: Gtk::CellRenderer::get_preferred_width_vfunc(Gtk::Widget&, int&, int&) const (cellrenderer.cc:1040) ==27575== by 0x50576DA: Gtk::CellRenderer_Class::get_preferred_width_vfunc_callback(_GtkCellRenderer*, _GtkWidget*, int*, int*) (cellrenderer.cc:68) ==27575== by 0x5659BC2: gtk_cell_renderer_get_preferred_width (gtkcellrenderer.c:1414) ==27575== by 0x564DF1A: gtk_cell_area_request_renderer (gtkcellarea.c:3600) ==27575== by 0x5650926: compute_size (gtkcellareabox.c:1533) ==27575== by 0x565121D: gtk_cell_area_box_get_preferred_width (gtkcellareabox.c:1822) ==27575== by 0x5649CB9: gtk_cell_area_get_preferred_width (gtkcellarea.c:2096) ==27575== by 0x58B94F5: gtk_tree_view_column_cell_get_size (gtktreeviewcolumn.c:2908) ==27575== by 0x589D151: validate_row (gtktreeview.c:6099) ==27575== by 0x589DAA1: validate_visible_area (gtktreeview.c:6312) ==27575== by 0x589EC00: do_presize_handler (gtktreeview.c:6775) ==27575== by 0x589EE5B: gtk_tree_view_bin_process_updates (gtktreeview.c:6830) ==27575== by 0x58A7FB7: gtk_tree_view_adjustment_changed (gtktreeview.c:11264) ==27575== by 0x58A8C16: gtk_tree_view_do_set_hadjustment (gtktreeview.c:11564) ==27575== by 0x5892717: gtk_tree_view_set_property (gtktreeview.c:1787) ==27575== by 0x5E6D098: object_set_property (gobject.c:1331) ==27575== by 0x5E6E3BB: g_object_set_valist (gobject.c:1863) ==27575== by 0x5E6E866: g_object_set (gobject.c:1969) ==27575== by 0x57C6A9D: gtk_scrolled_window_remove (gtkscrolledwindow.c:1999) ==27575== by 0x5072A28: Gtk::Container_Class::remove_callback(_GtkContainer*, _GtkWidget*) (container.cc:171) ==27575== by 0x5E6A80D: g_cclosure_marshal_VOID__OBJECT (gmarshal.c:644) ==27575== by 0x5E6833B: g_type_class_meta_marshal (gclosure.c:885) ==27575== by 0x5E68034: g_closure_invoke (gclosure.c:774) ==27575== by 0x5E7F944: signal_emit_unlocked_R (gsignal.c:3232) ==27575== by 0x5E7F1CB: g_signal_emit_valist (gsignal.c:3033) ==27575== by 0x5E7F4AA: g_signal_emit (gsignal.c:3090) ==27575== by 0x5686E71: gtk_container_remove (gtkcontainer.c:1539) ==27575== by 0x58D7494: gtk_widget_dispose (gtkwidget.c:10061) ==27575== by 0x5138187: Gtk::Widget_Class::dispose_vfunc_callback(_GObject*) (widget.cc:601) ==27575== by 0x5E6C7FC: g_object_run_dispose (gobject.c:1040) ==27575== by 0x51677F2: Gtk::Object::_release_c_instance() (object.cc:148) ==27575== by 0x5167C73: Gtk::Object::destroy_() (object.cc:260) ==27575== by 0x512AB6F: Gtk::TreeView::~TreeView() (treeview.cc:1140) ==27575== by 0x82F0D34: Glom::DbAddDel::~DbAddDel() (db_adddel.cc:126) ==27575== by 0x831D832: Glom::DbAddDel_WithButtons::~DbAddDel_WithButtons() (db_adddel_withbuttons.cc:55) ==27575== by 0x82C1948: Glom::Box_Data_List::~Box_Data_List() (box_data_list.cc:66) ==27575== by 0x8396757: Glom::DataWidgetChildren::Dialog_ChooseID::~Dialog_ChooseID() (dialog_choose_id.cc:71) ==27575== by 0x8396D10: Glom::DataWidgetChildren::Dialog_ChooseID::~Dialog_ChooseID() (dialog_choose_id.cc:79) ==27575== by 0x8371100: Glom::DataWidget::offer_related_record_id_find(Gnome::Gda::Value&) (datawidget.cc:665) ==27575== by 0x8370007: Glom::DataWidget::on_button_select_id() (datawidget.cc:582) ==27575== by 0x837729E: sigc::bound_mem_functor0<void, Glom::DataWidget>::operator()() const (in /opt/gnome30/bin/glom) ==27575== by 0x8376ECB: sigc::adaptor_functor<sigc::bound_mem_functor0<void, Glom::DataWidget> >::operator()() const (adaptor_trait.h:251) ==27575== by 0x83768A3: sigc::internal::slot_call0<sigc::bound_mem_functor0<void, Glom::DataWidget>, void>::call_it(sigc::internal::slot_rep*) (slot.h:103) ==27575== by 0x4141819: sigc::slot0<void>::operator()() const (slot.h:440) ==27575== by 0x551CBA2: Glib::SignalProxyNormal::slot0_void_callback(_GObject*, void*) (signalproxy.cc:95) ==27575== by 0x5E69CE7: g_cclosure_marshal_VOID__VOID (gmarshal.c:85) ==27575== by 0x5E68034: g_closure_invoke (gclosure.c:774) ==27575== by 0x5E7FE52: signal_emit_unlocked_R (gsignal.c:3372) ==27575== by 0x5E7F1CB: g_signal_emit_valist (gsignal.c:3033) ==27575== Address 0x0 is not stack'd, malloc'd or (recently) free'd
This patch brings the crash back: --- a/glom/mode_data/datawidget/dialog_choose_id.cc +++ b/glom/mode_data/datawidget/dialog_choose_id.cc @@ -75,7 +75,7 @@ Dialog_ChooseID::~Dialog_ChooseID() //Work around this bug (apparently in GTK+): //https://bugzilla.gnome.org/show_bug.cgi?id=660347 - m_alignment_parent->remove(); + //m_alignment_parent->remove(); }
The bug I fixed seemingly fixed the other thing... I don't know where exactly problem lies: 1. is it on C++ side that it deletes a wrapper at the beginning of dispose instead of its end. 2. is it on C side in general, because ideally all children of to-be-destroyed widget should be marked to-be-destroyed too, so no superfluous calls could be done. If I remember correctly - here specifically GtkScrolledWindow unsets some adjustments of its child and that makes that child wanting to redraw itself. So it calls some vfuncs which are in fact some methods of already destroyed C++ wrapper.
Created attachment 202706 [details] [review] Scrolledwindow: unset adjustments after removal, not before. Please either provide a way to reproduce it or a patch like the one from comment 5 (the current one does not apply now). In the meantime, please try patching gtk+ with attached patch. Note that it is untested at all, because I had some problems with running glom (something about glom python module not being installed).
Yes, that fixes the crash. I guess you should submit that as a GTK+ bug.
Filed a Gtk+ bug and added a dependency.
The workaround in comment #12 still seems to be necessary. Before glom crashes, I now see this warning (actually twice): glibmm-WARNING **: Glib::wrap_create_new_wrapper: Attempted to create a 2nd C++ wrapper for a C instance whose C++ wrapper has been deleted. Here is the gdb backtrace at that point:
+ Trace 229639
After that warning, but not before, valgrind says: glibmm-WARNING **: Failed to wrap object of type 'gtkmm__GtkTreeView'. Hint: this error is commonly caused by failing to call a library init() function. ==17231== Invalid read of size 4 ==17231== at 0x816B17C: Gtk::Widget::gobj() (widget.h:289) ==17231== by 0x4E1214B: Gtk::CellRenderer::get_preferred_width_vfunc(Gtk::Widget&, int&, int&) const (cellrenderer.cc:1040) ==17231== by 0x4E0FA02: Gtk::CellRenderer_Class::get_preferred_width_vfunc_callback(_GtkCellRenderer*, _GtkWidget*, int*, int*) (cellrenderer.cc:68) ==17231== by 0x5425808: gtk_cell_renderer_get_preferred_width (gtkcellrenderer.c:1465) ==17231== by 0x5419B1E: gtk_cell_area_request_renderer (gtkcellarea.c:3600) ==17231== by 0x541C52A: compute_size (gtkcellareabox.c:1533) ==17231== by 0x541CE21: gtk_cell_area_box_get_preferred_width (gtkcellareabox.c:1822) ==17231== by 0x54158BD: gtk_cell_area_get_preferred_width (gtkcellarea.c:2096) ==17231== by 0x568B00D: gtk_tree_view_column_cell_get_size (gtktreeviewcolumn.c:2908) ==17231== by 0x566EB8C: validate_row (gtktreeview.c:6082) ==17231== by 0x566F4D5: validate_visible_area (gtktreeview.c:6295) ==17231== by 0x5670618: do_presize_handler (gtktreeview.c:6758) ==17231== by 0x5670873: gtk_tree_view_bin_process_updates (gtktreeview.c:6813) ==17231== by 0x5679AFE: gtk_tree_view_adjustment_changed (gtktreeview.c:11268) ==17231== by 0x567A77A: gtk_tree_view_do_set_hadjustment (gtktreeview.c:11569) ==17231== by 0x566425B: gtk_tree_view_set_property (gtktreeview.c:1793) ==17231== by 0x5C5F383: object_set_property (gobject.c:1342) ==17231== by 0x5C6090B: g_object_set_valist (gobject.c:1937) ==17231== by 0x5C60DB6: g_object_set (gobject.c:2043) ==17231== by 0x559C413: gtk_scrolled_window_remove (gtkscrolledwindow.c:2003) ==17231== by 0x4E2AD50: Gtk::Container_Class::remove_callback(_GtkContainer*, _GtkWidget*) (container.cc:171) ==17231== by 0x5C5C9B5: g_cclosure_marshal_VOID__OBJECT (gmarshal.c:644) ==17231== by 0x5C5A4CF: g_type_class_meta_marshal (gclosure.c:885) ==17231== by 0x5C5A1C8: g_closure_invoke (gclosure.c:774) ==17231== by 0x5C7225C: signal_emit_unlocked_R (gsignal.c:3232) ==17231== by 0x5C71AE3: g_signal_emit_valist (gsignal.c:3033) ==17231== by 0x5C71DC2: g_signal_emit (gsignal.c:3090) ==17231== by 0x5452169: gtk_container_remove (gtkcontainer.c:1539) ==17231== by 0x56A922B: gtk_widget_dispose (gtkwidget.c:10101) ==17231== by 0x4EF08F7: Gtk::Widget_Class::dispose_vfunc_callback(_GObject*) (widget.cc:601) ==17231== by 0x5C5EAE7: g_object_run_dispose (gobject.c:1051) ==17231== by 0x4F1FF62: Gtk::Object::_release_c_instance() (object.cc:148) ==17231== by 0x4F203E3: Gtk::Object::destroy_() (object.cc:260) ==17231== by 0x4EE32DF: Gtk::TreeView::~TreeView() (treeview.cc:1140) ==17231== by 0x818A443: Glom::DbAddDel::~DbAddDel() (db_adddel.cc:126) ==17231== by 0x8199138: Glom::DbAddDel_WithButtons::~DbAddDel_WithButtons() (db_adddel_withbuttons.cc:55) ==17231== by 0x817A3C0: Glom::Box_Data_List::~Box_Data_List() (box_data_list.cc:66) ==17231== by 0x81C3938: Glom::DataWidgetChildren::Dialog_ChooseID::~Dialog_ChooseID() (dialog_choose_id.cc:72) ==17231== by 0x81C3B36: Glom::DataWidgetChildren::Dialog_ChooseID::~Dialog_ChooseID() (dialog_choose_id.cc:80) ==17231== by 0x81B5D03: Glom::DataWidget::offer_related_record_id_find(Gnome::Gda::Value&) (datawidget.cc:706) ==17231== by 0x81B574D: Glom::DataWidget::on_button_select_id() (datawidget.cc:609) ==17231== by 0x81B862F: sigc::bound_mem_functor0<void, Glom::DataWidget>::operator()() const (in /opt/gnome30/bin/glom) ==17231== by 0x81B8489: sigc::adaptor_functor<sigc::bound_mem_functor0<void, Glom::DataWidget> >::operator()() const (adaptor_trait.h:251) ==17231== by 0x81B821D: sigc::internal::slot_call0<sigc::bound_mem_functor0<void, Glom::DataWidget>, void>::call_it(sigc::internal::slot_rep*) (slot.h:103) ==17231== by 0x4146425: sigc::slot0<void>::operator()() const (slot.h:440) ==17231== by 0x52D4DAA: Glib::SignalProxyNormal::slot0_void_callback(_GObject*, void*) (signalproxy.cc:95) ==17231== by 0x5C5BE8F: g_cclosure_marshal_VOID__VOID (gmarshal.c:85) ==17231== by 0x5C5A1C8: g_closure_invoke (gclosure.c:774) ==17231== by 0x5C7276A: signal_emit_unlocked_R (gsignal.c:3372) ==17231== by 0x5C71AE3: g_signal_emit_valist (gsignal.c:3033) ==17231== Address 0x0 is not stack'd, malloc'd or (recently) free'd
Ah, I was wasting my time by testing that. The GTK+ patch has not been pushed.
Does this problem still exist after bug 605728 was fixed? (gtkmm 3.7.12 and 3.8.1) The fixes of bug 605728 might affect the cases that result in the message "Attempted to create a 2nd C++ wrapper for a C instance whose C++ wrapper has been deleted." The message in comment 3 in different. It's probably not related to bug 605728.
Yes, this seems to be fixed, presumably by your fix in gtkmm. Thanks. Now I have removed the workaround from glom's git master.