Files
punktfunk/packaging/gamescope/patches
enricobuehler 9e7713eecf
ci / bun-nix (pull_request) Successful in 27s
ci / web (pull_request) Successful in 1m1s
ci / docs-site (pull_request) Successful in 1m11s
ci / rust-arm64 (pull_request) Successful in 2m30s
ci / rust (pull_request) Successful in 4m47s
fix(gamescope): every session ended in a SIGSEGV at exit
Each gamescope-backed session left a coredump behind. It happened after the
compositor had finished its work — "Primary child shut down!", then the crash —
so the stream itself looked fine and it surfaced only as a steady drip of
coredumps and a non-zero exit from the spawn.

It is a static-destruction-order bug, not a race and not anything gamescope does
wrong at runtime. `g_device` (CVulkanDevice) and `g_output` (VulkanOutput_t) were
plain globals, so glibc ran their destructors from `__run_exit_handlers` once
main() returned. Those destructors call back into the driver —
`~CVulkanCmdBuffer` -> `vk.FreeCommandBuffers`, `~CVulkanTexture` -> `vk.Destroy*`
— but the Vulkan ICD has already been torn down and unloaded by then, so each
call jumps through a function pointer into an unmapped page. The faulting address
equalling the instruction pointer is the signature:

  #0  0x00007fe8fd1d1070 in ?? ()
  #1  CVulkanCmdBuffer::~CVulkanCmdBuffer   at rendervulkan.cpp:1543
  #9  std::vector<unique_ptr<CVulkanCmdBuffer>>::~vector  (g_device+1792)
  #10 CVulkanDevice::~CVulkanDevice         at rendervulkan.hpp:768
  #11 __run_exit_handlers / exit()

Patch 0006 gives both globals storage that is constructed exactly as before but
never destroyed; a union member is destroyed only if the union's destructor says
so, and ours deliberately does not. Nothing needs freeing there — the process is
exiting and the kernel reclaims the device, its command buffers and every GPU
allocation. Both objects are needed: pinning only the device relocated the fault
into ~VulkanOutput_t.

The `.pfhdrN` level deliberately stays at 4. It is a capability tier the host
probes before it spawns, and this patch adds no capability — bumping it would
advertise a tier that does not exist. Per the PKGBUILD's own rule this ships as a
`pkgrel` bump instead.

Verified on an NVIDIA box, all six patches `git am`-ing onto the pinned upstream
commit and then a RELEASE build (the shipped configuration):

  version banner   3.16.25-7-gea635c1+pfhdr4   (marker intact)
  patched, real spawn shape (2752x2064@120 --steam --xwayland-count 1)
                   6/6 exit 0
  distro control, same shape
                   SIGSEGV

Not filed upstream, though it is not punktfunk-specific and would apply as-is.

Unrelated and left alone: `--xwayland-count 0` dies much earlier, in main() at
wlserver.cpp:3215, dereferencing a null `gamescope_xwayland_server_t`. Punktfunk
always spawns with `--xwayland-count 1`, so that path is never taken here.
2026-08-08 19:21:39 +02:00
..