hyprwm / xdg-desktop-portal-hyprland

xdg-desktop-portal backend for Hyprland
BSD 3-Clause "New" or "Revised" License
273 stars 47 forks source link

Segfault in `wlrOnReady` when screensharing ends #141

Closed jaen closed 9 months ago

jaen commented 10 months ago

I'm trying to use the portal for screensharing, but it's being a bit wonky.

First I tried it in a Chrome-based browser (Brave), where I need to click through the xdph UI twice for the screeenshare to work and checking the restore token thing didn't work.

Then I tried it in Firefox, where the xdph UI shows only once, but the restore token didn't work on subsequent share either.

I decided to look in the logs and it turns out that xdph is segfaulting on screenshare end. I guess this is why the restore token doesn't work (because there's no chance for it to be persisted before the segfault takes the process down) and why Chrome shows the dialog twice – first for the tiny screen previews in it's own selection dialog, then when I select one the screenshare session for thumbnails finishes, xdph segfaults and gets restarted by systemd and since there was no chance for the token to get persisted, so I get the xdph UI again.

Here's the stacktrace in question:

Dec 01 20:33:40 hotaru xdg-desktop-portal-hyprland[265301]: [LOG] [screencopy] New session:
Dec 01 20:33:40 hotaru xdg-desktop-portal-hyprland[265301]: [LOG] [screencopy]  | /org/freedesktop/portal/desktop/request/1_132/webrtc_143565700
Dec 01 20:33:40 hotaru xdg-desktop-portal-hyprland[265301]: [LOG] [screencopy]  | /org/freedesktop/portal/desktop/session/1_132/webrtc_session1320270380
Dec 01 20:33:40 hotaru xdg-desktop-portal-hyprland[265301]: [LOG] [screencopy]  | appid:
Dec 01 20:33:40 hotaru xdg-desktop-portal-hyprland[265301]: [LOG] [screencopy] SelectSources:
Dec 01 20:33:40 hotaru xdg-desktop-portal-hyprland[265301]: [LOG] [screencopy]  | /org/freedesktop/portal/desktop/request/1_132/webrtc790211721
Dec 01 20:33:40 hotaru xdg-desktop-portal-hyprland[265301]: [LOG] [screencopy]  | /org/freedesktop/portal/desktop/session/1_132/webrtc_session1320270380
Dec 01 20:33:40 hotaru xdg-desktop-portal-hyprland[265301]: [LOG] [screencopy]  | appid:
Dec 01 20:33:40 hotaru xdg-desktop-portal-hyprland[265301]: [LOG] [screencopy] option persist_mode to 1
Dec 01 20:33:40 hotaru xdg-desktop-portal-hyprland[265301]: [LOG] [screencopy] unused option multiple
Dec 01 20:33:40 hotaru xdg-desktop-portal-hyprland[265301]: [LOG] [screencopy] unused option types
Dec 01 20:33:40 hotaru xdg-desktop-portal-hyprland[265301]: [LOG] [screencopy] restore data invalid / missing, prompting

Dec 01 20:33:49 hotaru systemd-coredump[267655]: [🡕] Process 265301 (.xdg-desktop-po) of user 1000 dumped core.

                                                 Module libpciaccess.so.0 without build-id.
                                                 Module libxml2.so.2 without build-id.
                                                 Module libncursesw.so.6 without build-id.
                                                 Module libxcb-dri3.so.0 without build-id.
                                                 Module libdrm_intel.so.1 without build-id.
                                                 Module libdrm_nouveau.so.2 without build-id.
                                                 Module libdrm_amdgpu.so.1 without build-id.
                                                 Module libelf.so.0 without build-id.
                                                 Module libdrm_radeon.so.1 without build-id.
                                                 Module libsensors.so.5 without build-id.
                                                 Module libz.so.1 without build-id.
                                                 Module libpipewire-module-session-manager.so without build-id.
                                                 Module libpipewire-module-metadata.so without build-id.
                                                 Module libpipewire-module-adapter.so without build-id.
                                                 Module libpipewire-module-client-device.so without build-id.
                                                 Module libpipewire-module-client-node.so without build-id.
                                                 Module libpcre.so.1 without build-id.
                                                 Module libselinux.so.1 without build-id.
                                                 Module libpipewire-module-protocol-native.so without build-id.
                                                 Module libdbus-1.so.3 without build-id.
                                                 Module libspa-dbus.so without build-id.
                                                 Module libspa-journal.so without build-id.
                                                 Module libspa-support.so without build-id.
                                                 Module libgpg-error.so.0 without build-id.
                                                 Module libzstd.so.1 without build-id.
                                                 Module liblzma.so.5 without build-id.
                                                 Module liblz4.so.1 without build-id.
                                                 Module libgcrypt.so.20 without build-id.
                                                 Module libcap.so.2 without build-id.
                                                 Module libXdmcp.so.6 without build-id.
                                                 Module libXau.so.6 without build-id.
                                                 Module libxcb.so.1 without build-id.
                                                 Module libffi.so.8 without build-id.
                                                 Module libsystemd.so.0 without build-id.
                                                 Module libxcb-randr.so.0 without build-id.
                                                 Module libexpat.so.1 without build-id.
                                                 Module libgcc_s.so.1 without build-id.
                                                 Module libstdc++.so.6 without build-id.
                                                 Module libsdbus-c++.so.1 without build-id.
                                                 Module libpipewire-0.3.so.0 without build-id.
                                                 Module libdrm.so.2 without build-id.
                                                 Module .xdg-desktop-portal-hyprland-wrapped without build-id.
                                                 Stack trace of thread 265301:
                                                 #0  0x000000000044f094 _ZN19CPipewireConnection7enqueueEPN17CScreencopyPortal8SSessionE (.xdg-desktop-portal-hyprland-wrapped + 0x4f094)
                                                 #1  0x000000000044fba4 _ZL10wlrOnReadyPvP24zwlr_screencopy_frame_v1jjj (.xdg-desktop-portal-hyprland-wrapped + 0x4fba4)
                                                 #2  0x00007f4bfdcd1052 ffi_call_unix64 (libffi.so.8 + 0xa052)
                                                 #3  0x00007f4bfdccee95 ffi_call_int (libffi.so.8 + 0x7e95)
                                                 #4  0x00007f4bfdccfa78 ffi_call (libffi.so.8 + 0x8a78)
                                                 #5  0x00007f4bfe3957e6 wl_closure_invoke (libwayland-client.so.0 + 0xa7e6)
                                                 #6  0x00007f4bfe391bd9 dispatch_event.isra.0 (libwayland-client.so.0 + 0x6bd9)
                                                 #7  0x00007f4bfe393534 wl_display_dispatch_queue_pending (libwayland-client.so.0 + 0x8534)
                                                 #8  0x00000000004646ab _ZN14CPortalManager14startEventLoopEv (.xdg-desktop-portal-hyprland-wrapped + 0x646ab)
                                                 #9  0x000000000040d3df main (.xdg-desktop-portal-hyprland-wrapped + 0xd3df)
                                                 #10 0x00007f4bfde63fce __libc_start_call_main (libc.so.6 + 0x27fce)
                                                 #11 0x00007f4bfde64089 __libc_start_main@@GLIBC_2.34 (libc.so.6 + 0x28089)
                                                 #12 0x000000000040e095 _start (.xdg-desktop-portal-hyprland-wrapped + 0xe095)

                                                 Stack trace of thread 265302:
                                                 #0  0x00007f4bfdf49a26 epoll_wait (libc.so.6 + 0x10da26)
                                                 #1  0x00007f4bfd9c7370 impl_pollfd_wait (libspa-support.so + 0x19370)
                                                 #2  0x00007f4bfd9b7c4d loop_iterate (libspa-support.so + 0x9c4d)
                                                 #3  0x00007f4bfe430aa0 do_loop (libpipewire-0.3.so.0 + 0x4caa0)
                                                 #4  0x00007f4bfdec7084 start_thread (libc.so.6 + 0x8b084)
                                                 #5  0x00007f4bfdf4960c __clone3 (libc.so.6 + 0x10d60c)

                                                 Stack trace of thread 265308:
                                                 #0  0x00007f4bfdec3c96 __futex_abstimed_wait_common (libc.so.6 + 0x87c96)
                                                 #1  0x00007f4bfdec6a67 pthread_cond_clockwait@GLIBC_2.30 (libc.so.6 + 0x8aa67)
                                                 #2  0x0000000000466981 _ZNSt6thread11_State_implINS_8_InvokerISt5tupleIJZN14CPortalManager14startEventLoopEvEUlvE0_EEEEE6_M_runEv (.xdg-desktop-portal-hyprland-wrapped + 0x66981)
                                                 #3  0x00007f4bfe211683 execute_native_thread_routine (libstdc++.so.6 + 0xe8683)
                                                 #4  0x00007f4bfdec7084 start_thread (libc.so.6 + 0x8b084)
                                                 #5  0x00007f4bfdf4960c __clone3 (libc.so.6 + 0x10d60c)

                                                 Stack trace of thread 265305:
                                                 #0  0x00007f4bfdec3c96 __futex_abstimed_wait_common (libc.so.6 + 0x87c96)
                                                 #1  0x00007f4bfdec6488 pthread_cond_wait@@GLIBC_2.3.2 (libc.so.6 + 0x8a488)
                                                 #2  0x00007f4bfb0f4289 cnd_wait (iris_dri.so + 0x10f289)
                                                 #3  0x00007f4bfb0a834b util_queue_thread_func (iris_dri.so + 0xc334b)
                                                 #4  0x00007f4bfb0f41c7 impl_thrd_routine (iris_dri.so + 0x10f1c7)
                                                 #5  0x00007f4bfdec7084 start_thread (libc.so.6 + 0x8b084)
                                                 #6  0x00007f4bfdf4960c __clone3 (libc.so.6 + 0x10d60c)

                                                 Stack trace of thread 265303:
                                                 #0  0x00007f4bfdec3c96 __futex_abstimed_wait_common (libc.so.6 + 0x87c96)
                                                 #1  0x00007f4bfdec6488 pthread_cond_wait@@GLIBC_2.3.2 (libc.so.6 + 0x8a488)
                                                 #2  0x00007f4bfb0f4289 cnd_wait (iris_dri.so + 0x10f289)
                                                 #3  0x00007f4bfb0a834b util_queue_thread_func (iris_dri.so + 0xc334b)
                                                 #4  0x00007f4bfb0f41c7 impl_thrd_routine (iris_dri.so + 0x10f1c7)
                                                 #5  0x00007f4bfdec7084 start_thread (libc.so.6 + 0x8b084)
                                                 #6  0x00007f4bfdf4960c __clone3 (libc.so.6 + 0x10d60c)

                                                 Stack trace of thread 265304:
                                                 #0  0x00007f4bfdec3c96 __futex_abstimed_wait_common (libc.so.6 + 0x87c96)
                                                 #1  0x00007f4bfdec6488 pthread_cond_wait@@GLIBC_2.3.2 (libc.so.6 + 0x8a488)
                                                 #2  0x00007f4bfb0f4289 cnd_wait (iris_dri.so + 0x10f289)
                                                 #3  0x00007f4bfb0a834b util_queue_thread_func (iris_dri.so + 0xc334b)
                                                 #4  0x00007f4bfb0f41c7 impl_thrd_routine (iris_dri.so + 0x10f1c7)
                                                 #5  0x00007f4bfdec7084 start_thread (libc.so.6 + 0x8b084)
                                                 #6  0x00007f4bfdf4960c __clone3 (libc.so.6 + 0x10d60c)

                                                 Stack trace of thread 265306:
                                                 #0  0x00007f4bfdec3c96 __futex_abstimed_wait_common (libc.so.6 + 0x87c96)
                                                 #1  0x00007f4bfdec6488 pthread_cond_wait@@GLIBC_2.3.2 (libc.so.6 + 0x8a488)
                                                 #2  0x00007f4bfb0f4289 cnd_wait (iris_dri.so + 0x10f289)
                                                 #3  0x00007f4bfb0a834b util_queue_thread_func (iris_dri.so + 0xc334b)
                                                 #4  0x00007f4bfb0f41c7 impl_thrd_routine (iris_dri.so + 0x10f1c7)
                                                 #5  0x00007f4bfdec7084 start_thread (libc.so.6 + 0x8b084)
                                                 #6  0x00007f4bfdf4960c __clone3 (libc.so.6 + 0x10d60c)

                                                 Stack trace of thread 265307:
                                                 #0  0x00007f4bfdec3ecf __GI___lll_lock_wait (libc.so.6 + 0x87ecf)
                                                 #1  0x00007f4bfdeca362 __pthread_mutex_lock@GLIBC_2.2.5 (libc.so.6 + 0x8e362)
                                                 #2  0x0000000000466796 _ZNSt6thread11_State_implINS_8_InvokerISt5tupleIJZN14CPortalManager14startEventLoopEvEUlvE_EEEEE6_M_runEv (.xdg-desktop-portal-hyprland-wrapped + 0x66796)
                                                 #3  0x00007f4bfe211683 execute_native_thread_routine (libstdc++.so.6 + 0xe8683)
                                                 #4  0x00007f4bfdec7084 start_thread (libc.so.6 + 0x8b084)
                                                 #5  0x00007f4bfdf4960c __clone3 (libc.so.6 + 0x10d60c)
                                                 ELF object binary architecture: AMD x86-64
Dec 01 20:33:49 hotaru systemd[5108]: xdg-desktop-portal-hyprland.service: Main process exited, code=dumped, status=11/SEGV
Dec 01 20:33:49 hotaru xdg-desktop-portal-hyprland[265301]: [LOG] execAndGet: WAYLAND_
Dec 01 20:33:49 hotaru systemd[5108]: xdg-desktop-portal-hyprland.service: Failed with result 'core-dump'.

When I ran xdph with --verbose it had a lot of additional logging (I can post whole log if you need it, but it's a lot of got poll events, so I decided to omit it for now) and I think the interesting part was here:

[LOG] [screencopy] New session:
[LOG] [screencopy]  | /org/freedesktop/portal/desktop/request/1_193/webrtc_1424623234
[LOG] [screencopy]  | /org/freedesktop/portal/desktop/session/1_193/webrtc_session2121010895
[LOG] [screencopy]  | appid:
[LOG] [screencopy] SelectSources:
[LOG] [screencopy]  | /org/freedesktop/portal/desktop/request/1_193/webrtc542951533
[LOG] [screencopy]  | /org/freedesktop/portal/desktop/session/1_193/webrtc_session2121010895
[LOG] [screencopy]  | appid:
[LOG] [screencopy] option persist_mode to 1
[LOG] [screencopy] unused option multiple
[LOG] [screencopy] unused option types
[LOG] [screencopy] restore data invalid / missing, prompting

# ...

[TRACE] [internal] Close Session 0x4fd460
[LOG] [screencopy] Session destroyed
[TRACE] [sc] wlrOnFlags for 0x508540
[TRACE] [sc] wlrOnDamage for 0x508540
[TRACE] [sc] wlr damage: 0 0 2566 1446
[TRACE] [sc] wlrOnReady for 0x508540
[TRACE] [sc] frame timestamp sec: 9868 nsec: 738009879 combined: 9868738009879ns
[TRACE] [pw] enqueue on 0x0

Where we can see that we get a nullptr here – https://github.com/hyprwm/xdg-desktop-portal-hyprland/blob/master/src/portals/Screencopy.cpp#L1119 – that is then dereferenced a couple lines later. I guess this means there's some race condition between the session being closed and xdph trying to access the last frame's data. Simply checking for nullptr in enqueue fixes the segfault, but it doesn't make the restore token work in neither of Brave nor Firefox – so either it's unrelated, or maybe a correct fix would be more complicated.

EDIT: I guess this might be related to this fix, because it looks like it fixed stream cleanup on session close – https://github.com/hyprwm/xdg-desktop-portal-hyprland/pull/130.

vaxerski commented 10 months ago

patch.txt try this

jaen commented 9 months ago

Sorry, didn't have chance to test this earlier. With the patch it doesn't fail, it only logs the issue as expected:

[LOG] [screencopy] Stream destroyed
[LOG] [screencopy] Session destroyed
[ERR] [pw] Attempted enqueue on invalid session??

FWIW the restore tokens still don't work in nether Brave nor Firefox.

vaxerski commented 9 months ago

FWIW the restore tokens still don't work in nether Brave nor Firefox.

unrelated

vaxerski commented 9 months ago

f5c3576c3b6cb1c31a8dfa3e4113f59bfe40cd71