Crash in workspace-basic metatest: default plugin assumes every window is on at least one workspace
Since upgrading to 43.1 (and then 43.2) in Debian, we've been seeing a crash in the installed-tests. This seems to happen reliably on the CI infrastructure that runs the installed-tests and on my laptop, but for whatever reason it doesn't happen at build-time or in a test VM.
Core was generated by `/usr/libexec/installed-tests/mutter-11/mutter-test-runner --all'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007f2a078f4914 in meta_workspace_index (workspace=0x0) at ../src/core/workspace.c:722
Download failed: Invalid argument. Continuing without source file ./obj-x86_64-linux-gnu/../src/core/workspace.c.
722 ../src/core/workspace.c: No such file or directory.
[Current thread is 1 (Thread 0x7f2a04cd1f80 (LWP 80172))]
(gdb) bt
#0 0x00007f2a078f4914 in meta_workspace_index (workspace=0x0) at ../src/core/workspace.c:722
#1 0x00007f2a00dc156d in switch_workspace
(plugin=0x558351a410a0 [MetaDefaultPlugin], from=0, to=1, direction=<optimized out>)
at ../src/compositor/plugins/default.c:571
#2 0x00007f2a078b5bcb in meta_plugin_manager_switch_workspace
(plugin_mgr=<optimized out>, from=<optimized out>, to=to@entry=1, direction=direction@entry=META_MOTION_RIGHT)
at ../src/compositor/meta-plugin-manager.c:316
#3 0x00007f2a078ad389 in meta_compositor_switch_workspace
(compositor=compositor@entry=0x558351a429c0 [MetaCompositorNative], from=from@entry=0x5583519e8200 [MetaWorkspace], to=to@entry=0x558351a559d0 [MetaWorkspace], direction=direction@entry=META_MOTION_RIGHT)
at ../src/compositor/compositor.c:682
#4 0x00007f2a078f6d81 in meta_workspace_activate_with_focus
(workspace=workspace@entry=0x558351a559d0 [MetaWorkspace], focus_this=focus_this@entry=0x0, timestamp=49315689)
at ../src/core/workspace.c:684
#5 0x00007f2a078f6f39 in meta_workspace_activate
(workspace=workspace@entry=0x558351a559d0 [MetaWorkspace], timestamp=<optimized out>)
at ../src/core/workspace.c:714
#6 0x00005583504244f6 in test_case_do
(error=0x7ffc060ffbb0, argv=<optimized out>, argc=<optimized out>, test=0x55835280d100)
at ../src/tests/test-runner.c:1062
#7 run_test
(context=context@entry=0x5583516f7880 [MetaContextTest], filename=0x558351743c20 "/usr/share/mutter-11/tests/stacking/workspace-basic.metatest", index=index@entry=31) at ../src/tests/test-runner.c:1277
#8 0x00005583504248e3 in run_tests (context=0x5583516f7880 [MetaContextTest], info=0x7ffc061003d0)
at ../src/tests/test-runner.c:1358
#9 0x00007f2a05e5af7a in ffi_call_unix64 () at ../src/x86/unix64.S:104
#10 0x00007f2a05e5a40e in ffi_call_int
(cif=<optimized out>, fn=0x5583504248a0 <run_tests>, rvalue=<optimized out>, avalue=<optimized out>, closure=<optimized out>) at ../src/x86/ffi64.c:673
#11 0x00007f2a05e5ab0d in ffi_call
(cif=cif@entry=0x7ffc060ffef0, fn=fn@entry=0x5583504248a0 <run_tests>, rvalue=rvalue@entry=0x7ffc060ffe50, avalue=avalue@entry=0x7ffc060ffe10) at ../src/x86/ffi64.c:710
#12 0x00007f2a07ae200d in g_cclosure_marshal_generic_va
(closure=0x55835172e220, return_value=0x7ffc061000b0, instance=<optimized out>, args_list=<optimized out>, marshal_data=<optimized out>, n_params=0, param_types=<optimized out>) at ../../../gobject/gclosure.c:1650
#13 0x00007f2a07ae15a9 in _g_closure_invoke_va
(closure=closure@entry=0x55835172e220, return_value=return_value@entry=0x7ffc061000b0, instance=instance@entry=0x5583516f7880, args=args@entry=0x7ffc06100160, n_params=0, param_types=0x0) at ../../../gobject/gclosure.c:895
#14 0x00007f2a07afabbf in g_signal_emit_valist
(instance=0x5583516f7880, signal_id=5, detail=<optimized out>, var_args=var_args@entry=0x7ffc06100160)
at ../../../gobject/gsignal.c:3456
#15 0x00007f2a07afadbf in g_signal_emit
(instance=instance@entry=0x5583516f7880, signal_id=<optimized out>, detail=detail@entry=0)
at ../../../gobject/gsignal.c:3606
#16 0x00007f2a07c46dc5 in run_tests_idle (user_data=0x5583516f7880) at ../src/tests/meta-context-test.c:221
#17 0x00007f2a0753e67f in g_main_dispatch (context=0x5583516fbeb0) at ../../../glib/gmain.c:3444
#18 g_main_context_dispatch (context=context@entry=0x5583516fbeb0) at ../../../glib/gmain.c:4162
#19 0x00007f2a0753ea38 in g_main_context_iterate
(context=0x5583516fbeb0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>)
at ../../../glib/gmain.c:4238
#20 0x00007f2a0753ecef in g_main_loop_run (loop=0x5583519d6ba0) at ../../../glib/gmain.c:4438
#21 0x00007f2a078d6c65 in meta_context_run_main_loop (context=<optimized out>, error=error@entry=0x7ffc06100380)
at ../src/core/meta-context.c:465
#22 0x00007f2a07c472e3 in meta_context_test_run_tests
(context_test=0x5583516f7880 [MetaContextTest], flags=flags@entry=META_TEST_RUN_FLAG_NONE)
I think the problem is that in frame 1, the window has unmanaging = 1
and workspace = NULL
:
(gdb) p *window
$1 = {parent_instance = {g_type_instance = {g_class = 0x558351abe860 [g_type: MetaWindowWayland/MetaWindow]},
ref_count = 1, qdata = 0x0}, display = 0x558351a4a050 [MetaDisplay], id = 2216980762, stamp = 4294967389,
monitor = 0x0, workspace = 0x0, client_type = META_WINDOW_CLIENT_TYPE_WAYLAND, surface = 0x5583527c4000,
xwindow = 0, frame = 0x0, depth = 24, xvisual = 0x0, desc = 0x5583526d98d0 "W93",
title = 0x55835267f2d0 "test/w/1", type = META_WINDOW_NORMAL, res_class = 0x55835285f240 "mutter-test-client",
res_name = 0x55835283b460 "mutter-test-client", role = 0x0, sm_client_id = 0x0, wm_client_machine = 0x0,
startup_id = 0x0, mutter_hints = 0x0, sandboxed_app_id = 0x0, gtk_theme_variant = 0x0, gtk_application_id = 0x0,
gtk_unique_bus_name = 0x0, gtk_application_object_path = 0x0, gtk_window_object_path = 0x0,
gtk_app_menu_object_path = 0x0, gtk_menubar_object_path = 0x0, xtransient_for = 0, xgroup_leader = 0,
xclient_leader = 0, transient_for = 0x0, initial_workspace = 0, initial_timestamp = 0, tile_mode = META_TILE_NONE,
tile_monitor_number = -1, edge_constraints = {top = META_EDGE_CONSTRAINT_NONE, right = META_EDGE_CONSTRAINT_NONE,
bottom = META_EDGE_CONSTRAINT_NONE, left = META_EDGE_CONSTRAINT_NONE}, tile_hfraction = -1,
preferred_output_winsys_id = 9223372036854775808, fullscreen_monitors = {top = 0x0, bottom = 0x0, left = 0x0,
right = 0x0}, frame_bounds = 0x0, shape_region = 0x0, opaque_region = 0x0, input_region = 0x0,
opacity = 255 '\377', struts = 0x0, sync_request_counter = 0, sync_request_serial = 0,
sync_request_wait_serial = 0, sync_request_timeout_id = 0, sync_request_alarm = 0, unmaps_pending = 0,
reparents_pending = 0, stable_sequence = 94, net_wm_user_time = 49315523, user_time_window = 0,
has_custom_frame_extents = 0, custom_frame_extents = {left = 0, right = 0, top = 0, bottom = 0}, rect = {x = 150,
y = 66, width = 300, height = 500}, saved_rect = {x = 150, y = 66, width = 500, height = 400},
saved_rect_fullscreen = {x = 0, y = 0, width = 0, height = 0}, unconstrained_rect = {x = 150, y = 66, width = 500,
height = 400}, buffer_rect = {x = 150, y = 66, width = 300, height = 500}, icon_geometry = {x = 0, y = 0,
width = 0, height = 0}, size_hints = {flags = 976, x = 0, y = 0, width = 0, height = 0, min_width = 87,
min_height = 47, max_width = 2147483647, max_height = 2147483647, width_inc = 1, height_inc = 1, min_aspect = {
x = 1, y = 2147483647}, max_aspect = {x = 2147483647, y = 1}, base_width = 0, base_height = 0,
win_gravity = 1}, layer = META_LAYER_NORMAL, stack_position = -1, close_dialog = 0x0, group = 0x0,
compositor_private = 0x0, attached_focus_window = 0x0, tile_match = 0x0, placement = {rule = 0x0,
state = META_PLACEMENT_STATE_UNCONSTRAINED, pending = {x = 0, y = 0, rel_x = 0, rel_y = 0}, current = {rel_x = 0,
rel_y = 0}}, unmanage_idle_id = 0, close_dialog_timeout_id = 0, client_pid = 80566, has_valid_cgroup = 1,
cgroup_path = 0x55835247f340, events_during_ping = 0, override_redirect = 0, maximized_horizontally = 0,
maximized_vertically = 0, maximize_horizontally_after_placement = 0, maximize_vertically_after_placement = 0,
minimize_after_placement = 0, saved_maximize = 0, shaded = 0, fullscreen = 0, urgent = 0,
require_fully_onscreen = 1, require_on_single_monitor = 1, require_titlebar_visible = 1, on_all_workspaces = 0,
on_all_workspaces_requested = 0, minimized = 0, tab_unminimized = 0, mapped = 1, hidden = 0,
visible_to_compositor = 0, known_to_compositor = 0, pending_compositor_effect = 4, iconic = 0,
initially_iconic = 0, initial_workspace_set = 0, initial_timestamp_set = 0, net_wm_user_time_set = 0,
icon_geometry_set = 0, input = 1, mwm_decorated = 1, mwm_border_only = 0, mwm_has_close_func = 1,
mwm_has_minimize_func = 1, mwm_has_maximize_func = 1, mwm_has_move_func = 1, mwm_has_resize_func = 1,
decorated = 0, border_only = 0, always_sticky = 0, has_close_func = 1, has_minimize_func = 1,
has_maximize_func = 1, has_shade_func = 0, has_move_func = 1, has_resize_func = 1, has_fullscreen_func = 1,
skip_taskbar = 0, skip_pager = 0, skip_from_window_list = 0, wm_state_above = 0, wm_state_below = 0,
wm_state_demands_attention = 0, has_focus = 0, appears_focused = 0, placed = 1, denied_focus_and_not_transient = 0,
showing_for_first_time = 0, unmanaging = 1, constructing = 0, keys_grabbed = 0, grab_on_frame = 0,
all_keys_grabbed = 0, withdrawn = 0, calc_placement = 0, shaken_loose = 0, have_focus_click_grab = 1,
disable_sync = 0, attached = 0, is_remote = 0, restore_focus_on_map = 0, is_alive = 1,
extended_sync_request_counter = 0, in_workspace_change = 0}
switch_workspace()
in src/compositor/plugins/default.c
assumes that every window in meta_get_window_actors (display)
is either on all workspaces or on a single workspace, but the invariant in src/core/window.c
is that every window is either on all workspaces, on a single workspace, or unmanaging:
/* If we're on all workspaces, then our new workspace must be NULL,
* otherwise it must be set, unless we're unmanaging. */
if (on_all_workspaces)
g_assert_null (workspace);
else
g_assert_true (window->unmanaging || workspace != NULL);
I think the solution is to make switch_workspace()
in src/compositor/plugins/default.c
do something reasonable if the window is being unmanaged, but I'm not sure what that reasonable thing would be.