protonscr

vrcompositor segfaults in SharedResourceManager leak check during shutdown after Steam Frame link drops (2.18.2 beta)

steamvropen
ValveSoftware/SteamVR-for-Linux#990 · opened 2026-10-05 by zeeboguy · updated 2026-10-07 · 2 comments · github
Zzeeboguy 2026-10-05 github

Describe the bug

When the Steam Frame drops its VRLink connection, SteamVR shuts down as expected after the 30s inactivity timeout. vrcompositor then crashes with SIGSEGV during its "Cleaning up" phase. The crash is inside the loop that logs SharedResourceManager: detected possible leak with type: %d id: 0x%lx. The loop makes a virtual call on a leaked resource whose object memory has already been zeroed or freed. The vtable pointer is null, so the call faults reading address 0x18.

vrserver itself exits gracefully afterwards. The user-visible effect is a core dump and a crash notification each time the headset disconnects.

Steps to reproduce

  1. Stream to the Steam Frame over the Frame Wi-Fi dongle.
  2. Let the headset leave the link (in this case the dongle logged DEAUTH_LEAVING from the headset AP).
  3. Wait for driver_vrlink's Connection inactive for 30.27 > 30 seconds. Sending quit event.
  4. vrcompositor segfaults while cleaning up.

Expected behavior

vrcompositor exits cleanly. At worst it logs the leak warnings without crashing.

Crash details

kernel: vrcompositor[2884572]: segfault at 18 ip 000057fd53908c1c sp 00007ffdd6ea3c40 error 4 in vrcompositor[238c1c,57fd5381e000+37d000]
Code: ... f0 41 83 45 08 01 48 8b 3b 48 8b 07 <ff> 50 18 89 c2 ...

Main thread (frames are offsets into the vrcompositor binary):

#0 vrcompositor+0x239c1c   call *0x18(%rax)   ; rax = 0 (null vtable)
#1 vrcompositor+0x2759c6
#2 vrcompositor+0x293868
#3 vrcompositor+0x293a98
#4 libc  __libc_start_main

Register state at the fault:

  • r15 = the format string "SharedResourceManager: detected possible leak with type: %d id: 0x%lx\n"
  • r14 = 0x1e002c03dc (the next resource id to be logged)
  • rdi = the object pointer; its first 32 bytes are all zero

The other threads were idle (libnvidia-glcore worker threads waiting on condition variables, plus one vrclient thread).

Last lines of vrcompositor.txt:

22:28:26.028754 [Info] - VR compositor shutting down
22:28:26.229064 [Info] - Cleaning up
22:28:26.229227 [Warning] - SharedResourceManager: detected possible leak with type: 3 id: 0x1002c03dc
...  (28 leak warnings total, ids 0x1002c03dc .. 0x1c002c03dc)
22:28:26.230150 [Warning] - SharedResourceManager: detected possible leak with type: 2 id: 0x1c002c03dc
<crash>

At the same time, vrserver logged 12 lines of Failed to unref VRCompositor resource 0x{2..d}002c03dc and then [vrserver] Graceful exit.

System information

  • SteamVR 2.18.2 (beta branch, buildid 25664061), vrlink 0.4.3 (20260930.6234839)
  • Headset: Steam Frame via Frame Wi-Fi dongle (28de:2432, rtw89_8852cu)
  • GPU: NVIDIA RTX 5080, driver 610.57.04 (open kernel modules)
  • OS: Arch Linux (Omarchy), kernel 7.2.5
  • Compositor: Hyprland 0.56.2, Wayland. vrcompositor uses CHmdWindowSDL: Using Wayland with a wp_drm_lease_device_v1 lease.
  • Launch options: QT_QPA_PLATFORM=xcb %command% (works around vrmonitor failing to load Qt platform plugins)

Possibly related (same session, same setup)

These may share a root cause in compositor/vrlink resource lifetime. I'm happy to file them separately.

  1. vrserver null this deref in driver_vrlink.so+0xc9950 on the "vrcomp" thread (seen twice: 2026-10-04 00:18 and 22:08). The first vrcompositor exits silently ~12 ms after "Startup Complete" (no core, no Xid). vrserver then logs 12x "Failed to unref VRCompositor resource". When a game launches, the second compositor fails with VRInitError_Compositor_CreateDriverDirectModeResolveTextures (it cannot allocate a 3240x3240 shared image), and vrserver segfaults during cleanup. Breakpad IDs: bp-133fe00d-e1a5-45ad-89f2-dbbe92261004 (vrserver), bp-cf6c7fee-3fde-4729-ad36-be5572261004 (assert).
  2. Steam client SIGSEGV in CDesktopStreamT when the desktop stream starts with WARNING: Desktop capture unavailable, try running Steam with -pipewire. A zero-fill memset ran ~424 KB past the end of a 32 MB /dev/shm mapping, with the full 6720x2560 three-monitor desktop size in a register.

A SteamVR system report and the core dump are available on request.

Zzeeboguy 2026-10-05 github

It happened again at 2026-10-04 22:48 (same setup, SteamVR 2.18.2 beta). This time one quit produced three core dumps. The vrcompositor crash is the same one reported above (same vrcompositor+0x239c1c / +0x2759c6 / +0x293868 / +0x293a98 main-thread stack, inside the "possible leak" loop). It came after vrserver's own shutdown watchdog fired, which may be relevant.

Timeline from the logs:

Time Process Event
22:48:04.287 vrmonitor Transition from 'SteamVRSystemState_Standby' to 'SteamVRSystemState_ShutdownRequested'
22:48:04–24 vrserver vrdashboard, vrwebhelper_main / _settings_desktop / _pairing / _systemui / _controllerbinding and steamwebhelper never exit. vrserver logs Kill process <pid>: <name> because it didn't quit in time for all 7 of them every 5 s (09.5, 14.5, 19.5, 24.5), so the kills don't appear to work.
22:48:14.551 vrserver vrlink: Connection inactive for 30.235475 > 30 seconds. Sending quit event.
22:48:24.788 vrserver Failed Watchdog timeout in thread Connection quitall after 20.031210 seconds. Aborting. (SIGABRT from the ThreadWatchdog thread, vrserver+0x2c54f8)
22:48:25.841 vrcompositor SIGSEGV in the SharedResourceManager leak loop (same stack as this issue)
22:48:26.557 vrmonitor Lost connection to VR Server
22:48:43.206 vrmonitor ASSERT: "Aborting due to ignoring Quit event after 5.0 seconds!" at /data/src/vrclient/hmdlatest.cpp:1851, then SIGABRT (from a Qt timer into vrclient.so+0x53b473)

Breakpad ID for the vrmonitor assert: bp-579ee805-f2a3-4358-afd4-aa91c2261004.

So on this run, the compositor crash may be a side effect of vrserver aborting under it, rather than only the use-after-free on a normal exit. The underlying hang seems to be that the web helpers (including the Steam client's steamwebhelper, which vrserver may not be able to kill) never acknowledge the quit, which runs the 20 s quitall watchdog out. There was no memory pressure (no OOM, ~9.6 GiB available).

Zzeeboguy 2026-10-07 github

Still happening on SteamVR 2.18.2 beta (build 25664061): five more vrcompositor cores on 2026-10-06, one at the end of every session. Two things are new.

1. It also happens on clean quits, not only after the vrserver watchdog abort. My previous comment guessed the crash might be a side effect of vrserver aborting under the compositor. That's not required. vrserver didn't abort at any of these five, and it logged a normal VR server shutting down afterwards:

Time What triggered the quit Fault
22:23:15 vrmonitor quit all in preparation for a restart (in-app restart) SEGV_ACCERR
22:35:52 vrlink: Connection inactive for 30.26 > 30 seconds. Sending quit event. SEGV_ACCERR
22:49:45 vrlink: Connection inactive for 30.27 > 30 seconds. Sending quit event. SEGV_MAPERR, addr 0x18
23:00:24 vrlink: Connection inactive for 30.26 > 30 seconds. Sending quit event. SEGV_ACCERR
23:42:06 vrmonitor has initiated a quit all SEGV_MAPERR, addr 0x18

Each crash comes right after Cleaning up and the run of SharedResourceManager: detected possible leak with type: N id: 0x... lines. None of these sessions had an NVIDIA Xid.

2. A second crash signature that comes from the same instruction. Three of the five don't show vrcompositor+0x239c1c as frame 0. Instead the PC is in anonymous heap memory (SEGV_ACCERR), and frame 1 is the usual vrcompositor+0x2759c6 → +0x293868 → +0x293a98. In gdb the faulting call is the same one in all five:

vrcompositor+0x239c1c:  call   *0x18(%rax)     ; rax = object's vtable pointer
  • MAPERR cases: the object's memory had been zeroed, so rax = 0 and loading 0x18(%rax) faults at address 0x18. This is what the original report shows.
  • ACCERR cases: the memory had been freed and reused by glibc malloc. The "vtable" in each of the three cores is a malloc chunk:
22:23  vtable @0x76ce484b9120: 0x00006a626f2e7964 ("dy.obj")  0x0000000000000d91 (chunk size)  ...  [+0x18] -> heap
22:35  vtable @0x74ad7c43e1f0: 0x0000000000000000  0x0000000000000151 (chunk size)  0x...7c000178 (arena)  [+0x18] -> heap
23:00  vtable @0x7bca24000418: arena free-list pointers (self-referencing 0x...24000418)            [+0x18] -> heap

So the call jumps to a heap address that isn't executable. This confirms the leak-cleanup loop calls a virtual method on resource objects that have already been freed. Whether it ends as a MAPERR or an ACCERR depends only on what took the freed memory.

If you're matching crash reports, both of these belong to this issue:

  • frame 0 vrcompositor+0x239c1c, SEGV_MAPERR at 0x18
  • frame 0 in an anonymous mapping, SEGV_ACCERR, frame 1 vrcompositor+0x2759c6

Setup is unchanged: Arch-based (Omarchy), Hyprland (Wayland, DRM lease), RTX 5080 on nvidia-open 610.57.04, Steam Frame over the vrlink dongle, Steam client beta.

Launch lines