wayfire icon indicating copy to clipboard operation
wayfire copied to clipboard

Crash when switching from laptop to external monitor

Open lcolitti opened this issue 1 year ago • 3 comments

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

lcolitti avatar Apr 07 '24 06:04 lcolitti

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?

lcolitti avatar Apr 08 '24 12:04 lcolitti

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.

lcolitti avatar Apr 08 '24 13:04 lcolitti

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?

ammen99 avatar Apr 09 '24 09:04 ammen99

Closing for now, feel free to reopen if the issue persists with latest git.

ammen99 avatar Jun 15 '24 14:06 ammen99