gnome-shell assertion failure with GLib 2.73.1 while g_object_real_dispose() cleans up weak refs
While trying to upgrade to GLib 2.73.1 I saw crashes in gnome-shell after unlocking the lock-screen, and while starting the gdm greeter after rebooting. They seem to be caused by assertion failure weak_locations != NULL
in g_weak_ref_set()
, and probably related to #2672 (closed):
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49
#1 0x00005573b23d31a2 in dump_gjs_stack_on_signal_handler (signo=6) at ../src/main.c:353
#2 0x00007f7e0bfab920 in <signal handler called> () at /lib/x86_64-linux-gnu/libc.so.6
#3 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49
#4 0x00007f7e0bf95546 in __GI_abort () at abort.c:79
#5 0x00007f7e0cee1dcc in g_assertion_message
(domain=<optimized out>, file=<optimized out>, line=<optimized out>, func=0x7f7e0d041c68 <__func__.0> "g_weak_ref_set", message=<optimized out>) at ../../../glib/gtestutils.c:3255
#6 0x00007f7e0cf41d8b in g_assertion_message_expr
(domain=domain@entry=0x7f7e0d03e4b0 "GLib-GObject", file=file@entry=0x7f7e0d040b4e "../../../gobject/gobject.c", line=line@entry=5064, func=func@entry=0x7f7e0d041c68 <__func__.0> "g_weak_ref_set", expr=expr@entry=0x7f7e0d040fba "weak_locations != NULL") at ../../../glib/gtestutils.c:3281
#7 0x00007f7e0d01bae6 in g_weak_ref_set (weak_ref=0x5573b51b92d8, object=object@entry=0x0)
at ../../../gobject/gobject.c:5064
#8 0x00007f7e0d00a2df in weak_unbind
(user_data=0x5573b51b92d0, where_the_object_was=0x5573b51b6fa0 [Gjs_status_keyboard_LayoutMenuItem])
at ../../../gobject/gbinding.c:407
#9 0x00007f7e0d0147ef in weak_refs_notify (data=0x5573b51b9440) at ../../../gobject/gobject.c:3265
#10 0x00007f7e0cef73f6 in g_data_remove_internal (datalist=0x5573b51b6fb0, keys=<optimized out>, n_keys=2)
at ../../../glib/gdataset.c:559
#11 0x00007f7e0cef7a35 in g_datalist_id_remove_multiple
(datalist=datalist@entry=0x5573b51b6fb0, keys=keys@entry=0x7fff03e90ca0, n_keys=n_keys@entry=2)
at ../../../glib/gdataset.c:774
#12 0x00007f7e0d014d11 in g_object_real_dispose (object=0x5573b51b6fa0 [Gjs_status_keyboard_LayoutMenuItem])
at ../../../gobject/gobject.c:1366
#13 0x00007f7e0bf25241 in st_widget_dispose (gobject=0x5573b51b6fa0 [Gjs_status_keyboard_LayoutMenuItem])
at ../src/st/st-widget.c:334
#14 0x00007f7e0d017099 in g_object_run_dispose (object=0x5573b51b6fa0 [Gjs_status_keyboard_LayoutMenuItem])
at ../../../gobject/gobject.c:1449
#15 0x00007f7e0c41a7c3 in clutter_actor_destroy () at /usr/lib/x86_64-linux-gnu/mutter-10/libmutter-clutter-10.so.0
#16 0x00007f7e0b5f67ea in () at /usr/lib/x86_64-linux-gnu/libffi.so.8
#17 0x00007f7e0b5f5923 in () at /usr/lib/x86_64-linux-gnu/libffi.so.8
#18 0x00007f7e0c53a3bc in () at /usr/lib/x86_64-linux-gnu/libgjs.so.0
#19 0x00007f7e0c53aa47 in () at /usr/lib/x86_64-linux-gnu/libgjs.so.0
#20 0x00007f7e09497640 in () at /usr/lib/x86_64-linux-gnu/libmozjs-91.so.0
#21 0x00007f7e0948a3d1 in () at /usr/lib/x86_64-linux-gnu/libmozjs-91.so.0
#22 0x00007f7e09496d5b in () at /usr/lib/x86_64-linux-gnu/libmozjs-91.so.0
#23 0x00007f7e094971e3 in () at /usr/lib/x86_64-linux-gnu/libmozjs-91.so.0
#24 0x00007f7e094988a3 in () at /usr/lib/x86_64-linux-gnu/libmozjs-91.so.0
#25 0x00007f7e09a8dcc7 in () at /usr/lib/x86_64-linux-gnu/libmozjs-91.so.0
#26 0x00007f7e09a8e19a in () at /usr/lib/x86_64-linux-gnu/libmozjs-91.so.0
#27 0x00001be1e37b9df4 in ()
#28 0x00005573b5118df0 in ()
(nothing useful below this point)
Applying !2776 (merged) (as of commit e95a6bdd) did not resolve this.
A workaround similar to !2756 (merged) seemed to avoid this crash, although I didn't test that version extensively:
diff --git a/gobject/gobject.c b/gobject/gobject.c
index df90898..9b862ad 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -1363,7 +1363,8 @@ g_object_real_dispose (GObject *object)
/* FIXME: This should be simplified down to a single remove_multiple() call.
* See https://gitlab.gnome.org/GNOME/glib/-/issues/2672 */
g_datalist_id_remove_multiple (&object->qdata, keys, 1);
- g_datalist_id_remove_multiple (&object->qdata, keys + 1, 2);
+ g_datalist_id_remove_multiple (&object->qdata, keys + 1, 1);
+ g_datalist_id_remove_multiple (&object->qdata, keys + 2, 1);
}
#ifdef G_ENABLE_DEBUG
/cc @pwithnall @peterb @3v1n0