gtk4-rs: dispose_template calls dispose twice which can cause segfaults

Bug description

This issue was extensively discussed quite a while ago in the gtk issue tracker but never made it here. https://gitlab.gnome.org/GNOME/gtk/-/issues/5834

Within gtk-rs it can be reproduced like this:

  • Subclass a complex widget that calls dispose on its own children (I used adw::ActionRow but there are probably examples in gtk as well)
  • Use templates
  • Use expressions
  • Put the widget in a listbox
  • Remove the widget again

The problem is that with the current implementation it is basically impossible to opt out of dispose_template making it impossible to subclass some types with templates.

Backtrace

0x00007ffff2d58080 in gtk_object_expression_weak_ref_cb () from /usr/lib/x86_64-linux-gnu/libgtk-4.so.1
(gdb) bt
#0  0x00007ffff2d58080 in gtk_object_expression_weak_ref_cb () at /usr/lib/x86_64-linux-gnu/libgtk-4.so.1
#1  0x00007ffff7b79df7 in weak_refs_notify () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#2  0x00007ffff36f072f in g_data_set_internal () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007ffff7b7a23d in g_object_real_dispose () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#4  0x000055555589fcb2 in glib::subclass::object::dispose<example::ui::components::task_row::imp::TaskRow> (obj=0x5555588e03f0)
    at /home/fina/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glib-0.18.1/src/subclass/object.rs:160
#5  0x00007ffff7b7acc0 in g_object_unref () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#6  0x00007ffff2dbbaf5 in gtk_list_box_remove () at /usr/lib/x86_64-linux-gnu/libgtk-4.so.1
#7  0x00007ffff2dbcb86 in gtk_list_box_bound_model_changed () at /usr/lib/x86_64-linux-gnu/libgtk-4.so.1
#8  0x00007ffff7b7543a in g_closure_invoke () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#9  0x00007ffff7b8996c in signal_emit_unlocked_R.isra.0 () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#10 0x00007ffff7b8b3f1 in signal_emit_valist_unlocked () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#11 0x00007ffff7b913c1 in g_signal_emit_valist () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#12 0x00007ffff7b91483 in g_signal_emit () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#13 0x00007ffff7c9ee7d in g_list_store_splice () at /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#14 0x0000555555876cd0 in gio::auto::list_store::ListStore::splice<glib::object::Object>
    (self=0x555558626ff8, position=4, n_removals=1, additions=...)
    at /home/fina/.cargo/registry/src/index.crates.io-6f17d22bba15001f/gio-0.18.1/src/list_store.rs:63
#15 0x0000555555876adb in gio::auto::list_store::ListStore::retain<example::ui::task_list::imp::{impl#19}::cleanup::{closure_env#0}> (self=0x555558626ff8, f=...) at /home/fina/.cargo/registry/src/index.crates.io-6f17d22bba15001f/gio-0.18.1/src/list_store.rs:121

About this issue

  • Original URL
  • State: closed
  • Created 10 months ago
  • Reactions: 2
  • Comments: 16 (16 by maintainers)

Most upvoted comments

From what I gather from the discussion in gtk is that we need to

  1. mark dispose_template as unsafe and
  2. move back to calling it manually in the few cases where it’s actually required.