tests/wayland/test-driver: Unset resource user data on finalize

Client connections may linger after the test driver is teared down;
handle this gracefully by unsetting the user data on the wl_resource,
and make the resource destructor a no-op, instead of where it would
otherwise remove itself from the resource list. This fixes this crash
seen in CI:

Received signal 11 (SIGSEGV)
 #0  g_list_remove() at ../glib/glist.c:596
 #1  test_driver_destructor() at ../src/tests/meta-wayland-test-driver.c:219
 #2  destroy_resource() at ../src/wayland-server.c:730
 #3  for_each_helper() at ../src/wayland-util.c:416
 #4  wl_map_for_each() at ../src/wayland-util.c:430
 #5  wl_client_destroy() at ../src/wayland-server.c:889
 #6  wl_display_destroy_clients() at ../src/wayland-server.c:1482
 #7  meta_wayland_compositor_prepare_shutdown() at ../src/wayland/meta-wayland.c:441
 #8  meta_context_dispose() at ../src/core/meta-context.c:667
 #9  g_object_unref() at ../gobject/gobject.c:3863
 #9  g_object_unref() at ../gobject/gobject.c:3780
 #10 glib_autoptr_clear_GObject() at /usr/include/glib-2.0/gobject/gobject-autocleanups.h:29
 #10 glib_autoptr_clear_MetaContext() at ../src/meta/meta-context.h:32
 #10 glib_autoptr_cleanup_MetaContext() at ../src/meta/meta-context.h:32
 #10 main() at ../src/tests/wayland-unit-tests.c:707
 #11 __libc_start_call_main() in /usr/lib64/libc.so.6
 #12 __libc_start_main() in /usr/lib64/libc.so.6
 #13 _start() in /builds/GNOME/mutter/build/src/tests/mutter-wayland-unit

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2601>
This commit is contained in:
Jonas Ådahl 2022-09-01 09:37:17 +02:00 committed by Marge Bot
parent 96aa0fb853
commit c7954be56e

View File

@ -214,7 +214,11 @@ static const struct test_driver_interface meta_test_driver_interface = {
static void static void
test_driver_destructor (struct wl_resource *resource) test_driver_destructor (struct wl_resource *resource)
{ {
MetaWaylandTestDriver *test_driver = wl_resource_get_user_data (resource); MetaWaylandTestDriver *test_driver;
test_driver = wl_resource_get_user_data (resource);
if (!test_driver)
return;
test_driver->resources = g_list_remove (test_driver->resources, resource); test_driver->resources = g_list_remove (test_driver->resources, resource);
} }
@ -246,6 +250,15 @@ static void
meta_wayland_test_driver_finalize (GObject *object) meta_wayland_test_driver_finalize (GObject *object)
{ {
MetaWaylandTestDriver *test_driver = META_WAYLAND_TEST_DRIVER (object); MetaWaylandTestDriver *test_driver = META_WAYLAND_TEST_DRIVER (object);
GList *l;
for (l = test_driver->resources; l; l = l->next)
{
struct wl_resource *resource = l->data;
wl_resource_set_user_data (resource, NULL);
}
g_clear_list (&test_driver->resources, NULL);
g_clear_pointer (&test_driver->test_driver, wl_global_destroy); g_clear_pointer (&test_driver->test_driver, wl_global_destroy);
g_clear_pointer (&test_driver->properties, g_hash_table_unref); g_clear_pointer (&test_driver->properties, g_hash_table_unref);