Crash when switching from laptop to external monitor
I've seen a couple of these crashes recently using wayfire git as of a few days ago ("29bed6ef switcher: fix handling when workspace becomes empty (#2309)") plus #2294 . This may be already fixed (or it might be a bug in my code), but wanted to report it.
Occurrence 1:
EE 05-04-24 11:09:12.092 - [src/core/output-layout.cpp:527] disabling output: eDP-1
II 05-04-24 11:09:12.104 - [src/core/output-layout.cpp:158] transfer views from eDP-1 -> DP-3
II 05-04-24 11:09:12.212 - [backend/drm/drm.c:790] connector eDP-1: Turning off
II 05-04-24 11:09:12.783 - [backend/drm/drm.c:786] connector DP-3: Modesetting with 2560x1440 @ 59.951 Hz
EE 05-04-24 11:09:12.848 - [src/main.cpp:140] Fatal error: Segmentation fault
EE 05-04-24 11:09:12.893 - #1 signal_handler(int) ../src/main.cpp:142
EE 05-04-24 11:09:13.177 - #2 __restore_rt libc_sigaction.c:?
EE 05-04-24 11:09:13.943 - #3 std::__uniq_ptr_impl<wf::render_manager::impl, std::default_delete<wf::render_manager::impl> >::_M_ptr() const /usr/include/c++/13/bits/unique_ptr.h:199 (discriminator 1)
EE 05-04-24 11:09:14.627 - #4 std::unique_ptr<wf::render_manager::impl, std::default_delete<wf::render_manager::impl> >::get() const /usr/include/c++/13/bits/unique_ptr.h:470
EE 05-04-24 11:09:15.326 - #5 std::unique_ptr<wf::render_manager::impl, std::default_delete<wf::render_manager::impl> >::operator->() const /usr/include/c++/13/bits/unique_ptr.h:464
EE 05-04-24 11:09:16.105 - #6 wf::render_manager::schedule_redraw() ../src/output/render-manager.cpp:1283 (discriminator 1)
EE 05-04-24 11:09:16.892 - #7 wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}::operator()(void*) const ../src/view/wlr-surface-node.cpp:124 (discriminator 2)
EE 05-04-24 11:09:17.567 - #8 void std::__invoke_impl<void, wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}&, void*>(std::__invoke_other, wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}&, void*&&) /usr/include/c++/13/bits/invoke.h:61
EE 05-04-24 11:09:18.207 - #9 std::enable_if<is_invocable_r_v<void, wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}&, void*>, void>::type std::__invoke_r<void, wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}&, void*>(wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}&, void*&&) /usr/include/c++/13/bits/invoke.h:117
EE 05-04-24 11:09:18.798 - #10 std::_Function_handler<void (void*), wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}>::_M_invoke(std::_Any_data const&, void*&&) /usr/include/c++/13/bits/std_function.h:291
EE 05-04-24 11:09:18.831 - #11 std::function<void (void*)>::operator()(void*) const ../src/util.cpp:591
EE 05-04-24 11:09:18.866 - #12 wf::wl_listener_wrapper::emit(void*) ../src/wl-listener-wrapper.tpp:59
EE 05-04-24 11:09:18.901 - #13 wf::handle_wrapped_listener(wl_listener*, void*) ../src/wl-listener-wrapper.tpp:11
EE 05-04-24 11:09:18.906 - #14 wl_signal_emit_mutable ??:?
EE 05-04-24 11:09:18.943 - #15 surface_commit_state ../subprojects/wlroots/types/wlr_compositor.c:507
EE 05-04-24 11:09:18.977 - #16 wlr_surface_unlock_cached ../subprojects/wlroots/types/wlr_compositor.c:871
EE 05-04-24 11:09:19.027 - #17 subsurface_handle_parent_commit ../subprojects/wlroots/types/wlr_subcompositor.c:278
EE 05-04-24 11:09:19.061 - #18 surface_commit_state ../subprojects/wlroots/types/wlr_compositor.c:483 (discriminator 3)
EE 05-04-24 11:09:19.096 - #19 surface_handle_commit ../subprojects/wlroots/types/wlr_compositor.c:523
Occurrence 2:
EE 07-04-24 15:22:47.477 - [src/core/output-layout.cpp:527] disabling output: eDP-1
II 07-04-24 15:22:47.486 - [src/core/output-layout.cpp:158] transfer views from eDP-1 -> DP-3
II 07-04-24 15:22:47.511 - [backend/drm/drm.c:790] connector eDP-1: Turning off
II 07-04-24 15:22:48.093 - [backend/drm/drm.c:786] connector DP-3: Modesetting with 2560x1440 @ 59.951 Hz
EE 07-04-24 15:22:48.139 - [src/main.cpp:140] Fatal error: Segmentation fault
EE 07-04-24 15:22:48.197 - #1 signal_handler(int) ../src/main.cpp:142
EE 07-04-24 15:22:48.461 - #2 __restore_rt libc_sigaction.c:?
EE 07-04-24 15:22:49.192 - #3 std::__uniq_ptr_impl<wf::render_manager::impl, std::default_delete<wf::render_manager::impl> >::_M_ptr() const /usr/include/c++/13/bits/unique_ptr.h:199 (discriminator 1)
EE 07-04-24 15:22:49.901 - #4 std::unique_ptr<wf::render_manager::impl, std::default_delete<wf::render_manager::impl> >::get() const /usr/include/c++/13/bits/unique_ptr.h:470
EE 07-04-24 15:22:50.575 - #5 std::unique_ptr<wf::render_manager::impl, std::default_delete<wf::render_manager::impl> >::operator->() const /usr/include/c++/13/bits/unique_ptr.h:464
EE 07-04-24 15:22:51.260 - #6 wf::render_manager::schedule_redraw() ../src/output/render-manager.cpp:1283 (discriminator 1)
EE 07-04-24 15:22:51.911 - #7 wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}::operator()(void*) const ../src/view/wlr-surface-node.cpp:124 (discriminator 2)
EE 07-04-24 15:22:52.532 - #8 void std::__invoke_impl<void, wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}&, void*>(std::__invoke_other, wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}&, void*&&) /usr/include/c++/13/bits/invoke.h:61
EE 07-04-24 15:22:53.268 - #9 std::enable_if<is_invocable_r_v<void, wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}&, void*>, void>::type std::__invoke_r<void, wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}&, void*>(wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}&, void*&&) /usr/include/c++/13/bits/invoke.h:117
EE 07-04-24 15:22:53.844 - #10 std::_Function_handler<void (void*), wf::scene::wlr_surface_node_t::wlr_surface_node_t(wlr_surface*, bool)::{lambda(void*)#2}>::_M_invoke(std::_Any_data const&, void*&&) /usr/include/c++/13/bits/std_function.h:291
EE 07-04-24 15:22:53.878 - #11 std::function<void (void*)>::operator()(void*) const ../src/util.cpp:591
EE 07-04-24 15:22:53.911 - #12 wf::wl_listener_wrapper::emit(void*) ../src/wl-listener-wrapper.tpp:59
EE 07-04-24 15:22:53.944 - #13 wf::handle_wrapped_listener(wl_listener*, void*) ../src/wl-listener-wrapper.tpp:11
EE 07-04-24 15:22:53.949 - #14 wl_signal_emit_mutable ??:?
EE 07-04-24 15:22:53.983 - #15 surface_commit_state ../subprojects/wlroots/types/wlr_compositor.c:507
EE 07-04-24 15:22:54.018 - #16 wlr_surface_unlock_cached ../subprojects/wlroots/types/wlr_compositor.c:871
EE 07-04-24 15:22:54.061 - #17 subsurface_handle_parent_commit ../subprojects/wlroots/types/wlr_subcompositor.c:278
EE 07-04-24 15:22:54.095 - #18 surface_commit_state ../subprojects/wlroots/types/wlr_compositor.c:483 (discriminator 3)
EE 07-04-24 15:22:54.132 - #19 surface_handle_commit ../subprojects/wlroots/types/wlr_compositor.c:523
I managed to reproduce this with something like:
$ swaylock & sleep 1; python create_wayland_output.py & (sleep 0.05; python destroy_wayland_output.py WL-1)
Frame #7 in the stack trace is:
124 for (auto& [wo, _] : visibility)
125 {
126 wo->render->schedule_redraw();
127 }
Adding logging suggests that wo is being deleted: wo->render is null and wo->handle->name is garbage. The wo->handle of the wo being deleted matches WL-1. Presumably this code is racing with the on_output_remove callback a few lines below - that would remove the output from visibility and the code snippet above wouldn't crash.
I can't get this to crash if I comment out this code in session-lock.cpp that responds to output_changed events:
if (output_state->surface_node)
{
// output_state->surface_node->configure(size);
}
I'm not sure if that code is incorrect per se. You could argue it's a problem that the render code crashes if wlr-surface is committed on a deleted output. This won't happen to regular views because they'll be moved to other outputs when the output is deleted, but I guess it could happen to layer-shell views which are tied to a given output?
@ammen99 any thoughts?
I thought de3f82b0bcf13c6e4a0db88a3b0d7cb6cb77d020 and 048e8d7bc8e299998b28d12cd4f4f2697bb70091 would fix this, but with those commits it looks like the code crashes in wf::wlr_surface_controller_t::update_subsurface_order_and_position instead.
Not sure whether you're on Matrix and following the discussion there, there is work on some kind of fuzz tests and since recently they also include output hotplug, so I had to fix a few related crashes in #2325. Maybe that PR helps?
Closing for now, feel free to reopen if the issue persists with latest git.