Segfault in desktop-shell when focused client shuts down abruptly
Under certain conditions, when a focused client is shut down abruptly weston/desktop-shell crashes.
This is the result of a signal listener being removed from within the invocation of the previous listener in the listener list. wl_signal_emit uses wl_list_for_each_safe() but this is safe only for removal of the currently invoked listener.
In this particular case, when emitting the destroy_signal for a surface, the
focus_state->surface_destroy_listener is notified first and down the line calls weston_keyboard_set_focus() which removes the
seat->saved_kbd_focus_listener. The saved_kbd_focus_listener happens to be the next listener in the surface's destroy_signal listener list, wreaking havoc on the listener iteration.
- Start weston with desktop-shell with X11 backend
- Start a weston client A (e.g., weston-terminal)
- Start a second weston client B from an X11 terminal (e.g., another weston-terminal)
- Click on client B's window
- Ctrl-C client B
Thread 1 "weston" received signal SIGSEGV, Segmentation fault. 0x00007ffff7d76615 in wl_signal_emit (signal=0x555555c8adc8, data=0x555555c8adc0) at /usr/include/wayland-server-core.h:477 477 wl_list_for_each_safe(l, next, &signal->listener_list, link) (gdb) bt #0 0x00007ffff7d76615 in wl_signal_emit (signal=0x555555c8adc8, data=0x555555c8adc0) at /usr/include/wayland-server-core.h:477 #1 0x00007ffff7d7b76d in weston_surface_destroy (surface=0x555555c8adc0) at ../libweston/compositor.c:2220 #2 0x00007fffeefee60e in fade_out_done_idle_cb (data=0x555555591440) at ../desktop-shell/shell.c:2335 #3 0x00007ffff7d4731b in wl_event_loop_dispatch_idle (loop=loop@entry=0x555555562f00) at ../src/event-loop.c:969 #4 0x00007ffff7d47422 in wl_event_loop_dispatch (loop=0x555555562f00, timeout=timeout@entry=-1) at ../src/event-loop.c:1032 #5 0x00007ffff7d459e5 in wl_display_run (display=0x555555568fd0) at ../src/wayland-server.c:1351 #6 0x00007ffff7fbd47f in wet_main (argc=1, argv=0x7fffffffd938) at ../compositor/main.c:3398 #7 0x0000555555555155 in main (argc=6, argv=0x7fffffffd938) at ../compositor/executable.c:33