[gtk4.12] Segfaults and infinite loops when disposing of ListViews
Steps to reproduce
Do something with a ListView and then destroy it. Dragging without dropping seems to be enough, but I've seen the crash without that. It does seem to require some form of interaction beyond just scrolling.
- Open Nautilus to a directory
- Drag a file around. You don't need to do anything with it, just drag it around a little. Sometimes it crashes without this.
- Switch to another directory
- Segfault
In my application I only see crashes with ColumnViews while GridViews are fine, but Nautilus nightly (flatpak) seems to crash with both.
Version information
- GTK 4.12.4, and whatever the nightly flatpak of Nautilus uses
- Linux, x11, Fedora 39
Warnings
There are no warnings, at least not every time. I once got a warning about broken accounting for state for the ColumnListView, but I also got those for GridViews and I've never seen a grid view crash the same way in my application.
Backtrace
From my application, since I've only got Nautilus nightly via flatpak:
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007f2a8bc82697 in gtk_column_list_view_create_list_widget (base=0x558e3edc15f0) at ../gtk/gtkcolumnview.c:183
Downloading source file /usr/src/debug/gtk4-4.12.4-1.fc39.x86_64/redhat-linux-build/../gtk/gtkcolumnview.c
183 result = gtk_column_view_row_widget_new (gtk_list_view_get_factory (self->listview), FALSE);
[Current thread is 1 (Thread 0x7f2a89a2a000 (LWP 1878489))]
warning: Missing auto-load script at offset 0 in section .debug_gdb_scripts
of file ...
Use `info auto-load python-scripts [REGEXP]' to list them.
Missing separate debuginfos, use: dnf debuginfo-install xorg-x11-drv-nvidia-libs-545.29.06-2.fc39.x86_64
(gdb) bt full
#0 0x00007f2a8bc82697 in gtk_column_list_view_create_list_widget (base=0x558e3edc15f0) at ../gtk/gtkcolumnview.c:183
self = <optimized out>
result = <optimized out>
i = <optimized out>
#1 0x00007f2a8bd17fb3 in gtk_list_item_manager_ensure_items
(self=<optimized out>, change=0x7ffee46d79e0, update_start=147, update_diff=147) at ../gtk/gtklistitemmanager.c:1359
item = 0x558e3f699090
tile = 0x558e3f4c6450
header = <optimized out>
insert_after = 0x0
position = 0
i = 0
n_items = <optimized out>
query_n_items = 147
offset = 0
tracked = 1
has_sections = 0
#2 0x00007f2a8bd1c04f in gtk_list_item_manager_model_items_changed_cb
(model=<optimized out>, position=<optimized out>, removed=<optimized out>, added=<optimized out>, self=<optimized out>)
at ../gtk/gtklistitemmanager.c:1567
change = {deleted_items = 0x0, recycled_items = {head = 0x0, tail = 0x0, length = 0}, recycled_headers = {head = 0x0, tail = 0x0, length = 0}}
l = <optimized out>
n_items = 147
#3 0x00007f2a8b7b352a in g_closure_invoke
(closure=0x558e3f5624b0, return_value=0x0, n_param_values=4, param_values=0x7ffee46d7c40, invocation_hint=0x7ffee46d7b90)
at ../gobject/gclosure.c:832
marshal = 0x7f2a8ba30c10 <_g_cclosure_marshal_VOID__UINT_UINT_UINT>
marshal_data = 0x0
in_marshal = 0
real_closure = 0x558e3f562490
__func__ = "g_closure_invoke"
#4 0x00007f2a8b7e1fec in signal_emit_unlocked_R.isra.0
(node=node@entry=0x7ffee46d7d60, detail=detail@entry=0, instance=instance@entry=0x558e3e51a1d0, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7ffee46d7c40) at ../gobject/gsignal.c:3980
tmp = <optimized out>
handler = 0x558e3fb17a10
accumulator = <optimized out>
emission = {next = 0x7ffee46d8170, instance = 0x558e3e51a1d0, ihint = {signal_id = 2, detail = 0, run_type = (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACCUMULATOR_FIRST_RUN)}, state = EMISSION_RUN, chain_type = 0x4}
class_closure = <optimized out>
hlist = <optimized out>
handler_list = 0x558e3e678e70
return_accu = <optimized out>
accu = {g_type = 0x0, data = {{v_int = 0, v_uint = 0, v_long = 0, v_ulong = 0, v_int64 = 0, v_uint64 = 0, v_float = 0, v_double = 0, v_pointer = 0x0}, {v_int = 0, v_uint = 0, v_long = 0, v_ulong = 0, v_int64 = 0, v_uint64 = 0, v_float = 0, v_double = 0, v_pointer = 0x0}}}
signal_id = <optimized out>
max_sequential_handler_number = <optimized out>
return_value_altered = <optimized out>
n_params = <optimized out>
EMIT_RESTART = <optimized out>
__func__ = {<optimized out> <repeats 23 times>}
#5 0x00007f2a8b7d2d59 in signal_emit_valist_unlocked
(instance=instance@entry=0x558e3e51a1d0, signal_id=signal_id@entry=2, detail=detail@entry=0, var_args=var_args@entry=0x7ffee46d7ed0) at ../gobject/gsignal.c:3612
instance_and_params = <optimized out>
param_values = <optimized out>
node = <optimized out>
i = <optimized out>
node_copy = Python Exception <class 'gdb.error'>: value has been optimized out
{signal_id = 2, itype = , name = 0x7f2a8bb2633d "items-changed", destroyed = 0, flags = 2, n_params = 3, single_va_closure_is_valid = 1, single_va_closure_is_after = 0, param_types = 0x558e3e2d7110, return_type = 0x4, class_closure_bsa = 0x0, accumulator = 0x0, c_marshaller = 0x7f2a8ba30c10 <_g_cclosure_marshal_VOID__UINT_UINT_UINT>, va_marshaller = 0x7f2a8ba30070 <_g_cclosure_marshal_VOID__UINT_UINT_UINTv>, emission_hooks = 0x0, single_va_closure = 0x0}
__func__ = "signal_emit_valist_unlocked"
#6 0x00007f2a8b7d2f91 in g_signal_emit_valist
(instance=0x558e3e51a1d0, signal_id=2, detail=0, var_args=var_args@entry=0x7ffee46d7ed0) at ../gobject/gsignal.c:3355
#7 0x00007f2a8b7d3053 in g_signal_emit (instance=instance@entry=0x558e3e51a1d0, signal_id=<optimized out>, detail=detail@entry=0)
at ../gobject/gsignal.c:3675
var_args = {{gp_offset = 48, fp_offset = 48, overflow_arg_area = 0x7ffee46d7fb0, reg_save_area = 0x7ffee46d7ef0}}
#8 0x00007f2a8ba7f7d4 in g_list_model_items_changed (list=list@entry=0x558e3e51a1d0, position=position@entry=0, removed=removed@entry=0, added=added@entry=147) at ../gio/glistmodel.c:323
__func__ = "g_list_model_items_changed"
#9 0x00007f2a8bd32c45 in gtk_multi_selection_items_changed_cb (model=0x558e3f1d1680, position=0, removed=0, added=147, self=0x558e3e51a1d0) at ../gtk/gtkmultiselection.c:289
iter = {dummy1 = 0x558e3e51a250, dummy2 = 0x7ffee46d8180, dummy3 = 0x7ffee46d8010, dummy4 = 8, dummy5 = 32554, dummy6 = 0x12}
item = 0x0
pos_pointer = 0x7ffee46d8230
pending = <optimized out>
i = <optimized out>