Spinbuttons emit value_changed in destructor of parent window
When destroying a Window while a SpinButton in it still has pending edits, the spinbutton emits value_changed in the dtor which can lead to segfaults as the dtor as the dtor of my class has already run.
Here's a test case:ctest.cpp
In the main window, click the button, then type something in the spinbutton in the window that opens and then press escape. The application should now crash.
Here's a backtrace:
#0 0x557eb1a437a1 in TestWindow::handle_value_changed() (/tmp/simple+0xb7a1)
#1 0x557eb1a48bb0 in sigc::bound_mem_functor0<void, TestWindow>::operator()() const (/tmp/simple+0x10bb0)
#2 0x557eb1a4808b in sigc::adaptor_functor<sigc::bound_mem_functor0<void, TestWindow> >::operator()() const (/tmp/simple+0x1008b)
#3 0x557eb1a470d1 in sigc::internal::slot_call0<sigc::bound_mem_functor0<void, TestWindow>, void>::call_it(sigc::internal::slot_rep*) (/tmp/simple+0xf0d1)
#4 0x7f8ad344cc9c in Glib::SignalProxyNormal::slot0_void_callback(_GObject*, void*) (/usr/lib/libglibmm-2.4.so.1+0x5bc9c)
#5 0x7f8ad3093fcf in g_closure_invoke (/usr/lib/libgobject-2.0.so.0+0x13fcf)
#6 0x7f8ad30c0b05 (/usr/lib/libgobject-2.0.so.0+0x40b05)
#7 0x7f8ad30b1c84 in g_signal_emit_valist (/usr/lib/libgobject-2.0.so.0+0x31c84)
#8 0x7f8ad30b1f13 in g_signal_emit (/usr/lib/libgobject-2.0.so.0+0x31f13)
#9 0x7f8ad3a4f8db (/usr/lib/libgtk-3.so.0+0x28b8db)
#10 0x7f8ad3093fcf in g_closure_invoke (/usr/lib/libgobject-2.0.so.0+0x13fcf)
#11 0x7f8ad30c0837 (/usr/lib/libgobject-2.0.so.0+0x40837)
#12 0x7f8ad30b1c84 in g_signal_emit_valist (/usr/lib/libgobject-2.0.so.0+0x31c84)
#13 0x7f8ad30b1f13 in g_signal_emit (/usr/lib/libgobject-2.0.so.0+0x31f13)
#14 0x7f8ad3864a77 in gtk_adjustment_set_value (/usr/lib/libgtk-3.so.0+0xa0a77)
#15 0x7f8ad3a50605 in gtk_spin_button_update (/usr/lib/libgtk-3.so.0+0x28c605)
#16 0x7f8ad3a50a48 (/usr/lib/libgtk-3.so.0+0x28ca48)
#17 0x7f8ad3848fd7 (/usr/lib/libgtk-3.so.0+0x84fd7)
#18 0x7f8ad3093fcf in g_closure_invoke (/usr/lib/libgobject-2.0.so.0+0x13fcf)
#19 0x7f8ad30c0966 (/usr/lib/libgobject-2.0.so.0+0x40966)
#20 0x7f8ad30b16cb in g_signal_emit_valist (/usr/lib/libgobject-2.0.so.0+0x316cb)
#21 0x7f8ad30b1f13 in g_signal_emit (/usr/lib/libgobject-2.0.so.0+0x31f13)
#22 0x7f8ad3b08814 (/usr/lib/libgtk-3.so.0+0x344814)
#23 0x7f8ad3b07a7a in gtk_widget_send_focus_change (/usr/lib/libgtk-3.so.0+0x343a7a)
#24 0x7f8ad3b167a1 (/usr/lib/libgtk-3.so.0+0x3527a1)
#25 0x7f8ad3b16e59 (/usr/lib/libgtk-3.so.0+0x352e59)
#26 0x7f8ad4513842 in Gtk::Window_Class::set_focus_callback(_GtkWindow*, _GtkWidget*) (/usr/lib/libgtkmm-3.0.so.1+0x310842)
#27 0x7f8ad3092a45 in g_cclosure_marshal_VOID__OBJECTv (/usr/lib/libgobject-2.0.so.0+0x12a45)
#28 0x7f8ad30b1dd3 in g_signal_emit_valist (/usr/lib/libgobject-2.0.so.0+0x31dd3)
#29 0x7f8ad30b1f13 in g_signal_emit (/usr/lib/libgobject-2.0.so.0+0x31f13)
#30 0x7f8ad3b10e7c (/usr/lib/libgtk-3.so.0+0x34ce7c)
#31 0x7f8ad30a1a80 in g_object_run_dispose (/usr/lib/libgobject-2.0.so.0+0x21a80)
#32 0x7f8ad4513698 in Gtk::Window::_release_c_instance() (/usr/lib/libgtkmm-3.0.so.1+0x310698)
#33 0x7f8ad45142b0 in Gtk::Window::~Window() (/usr/lib/libgtkmm-3.0.so.1+0x3112b0)
#34 0x557eb1a438fd in TestWindow::~TestWindow() (/tmp/simple+0xb8fd)
#35 0x557eb1a43961 in TestWindow::~TestWindow() (/tmp/simple+0xb961)
#36 0x557eb1a43d00 in MainWindow::MainWindow()::{lambda()#1}::operator()() const::{lambda()#1}::operator()() const (/tmp/simple+0xbd00)
#37 0x557eb1a483e7 in sigc::adaptor_functor<MainWindow::MainWindow()::{lambda()#1}::operator()() const::{lambda()#1}>::operator()() const (/tmp/simple+0x103e7)
#38 0x557eb1a4748e in sigc::internal::slot_call0<MainWindow::MainWindow()::{lambda()#1}::operator()() const::{lambda()#1}, void>::call_it(sigc::internal::slot_rep*) (/tmp/simple+0xf48e)
#39 0x7f8ad44f9df9 (/usr/lib/libgtkmm-3.0.so.1+0x2f6df9)
#40 0x7f8ad3093fcf in g_closure_invoke (/usr/lib/libgobject-2.0.so.0+0x13fcf)
#41 0x7f8ad30c0b05 (/usr/lib/libgobject-2.0.so.0+0x40b05)
#42 0x7f8ad30b1c84 in g_signal_emit_valist (/usr/lib/libgobject-2.0.so.0+0x31c84)
#43 0x7f8ad30b1f13 in g_signal_emit (/usr/lib/libgobject-2.0.so.0+0x31f13)
#44 0x7f8ad3af8670 in gtk_widget_hide (/usr/lib/libgtk-3.so.0+0x334670)
#45 0x7f8ad30a1a80 in g_object_run_dispose (/usr/lib/libgobject-2.0.so.0+0x21a80)
#46 0x7f8ad39a7121 in gtk_main_do_event (/usr/lib/libgtk-3.so.0+0x1e3121)
#47 0x7f8ad3b040bc (/usr/lib/libgtk-3.so.0+0x3400bc)
#48 0x7f8ad36f76ad (/usr/lib/libgdk-3.so.0+0x2d6ad)
#49 0x7f8ad2f99b2a in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x54b2a)
#50 0x7f8ad2fefe78 (/usr/lib/libglib-2.0.so.0+0xaae78)
#51 0x7f8ad2f97251 in g_main_context_iteration (/usr/lib/libglib-2.0.so.0+0x52251)
#52 0x7f8ad358126d in g_application_run (/usr/lib/libgio-2.0.so.0+0xd226d)
#53 0x557eb1a426ef in main (/tmp/simple+0xa6ef)
#54 0x7f8ad2a402cf (/usr/lib/libc.so.6+0x232cf)
#55 0x7f8ad2a40389 in __libc_start_main (/usr/lib/libc.so.6+0x23389)
#56 0x557eb1a42444 in _start ../sysdeps/x86_64/start.S:115
sigc++ automatic signal disconnection doesn't save us here as the sigc::trackable
is at the very bottom at the class hierarchy, so I believe the signal handler only gets disconnected after the GtkWindow is gone. A suitable workaround is calling unset_focus()
before closing the window so we don't get the focus change in the dtor.
Not entirely sure if this is a Gtkmm or a Gtk issue as I can't quite tell how this behaviour would affect applications written in C.