Thunks crash (NoExec segfault) inside Steam Linux Runtime / pressure-vessel containers — overlay redirection is host-side only, and pv's graphics capture copies guest thunk stubs into the container
- Dominant language
- C++
- Stars
- 8k
- Forks
- 351
- Avg merge
- 12h 31m
- Merged PRs (30d)
- 102
Description
## Summary
Running x86_64 Vulkan apps inside a Steam Linux Runtime container (pressure-vessel, with
its FEX interpreter-root integration active) with ThunksDB enabled reliably segfaults with:
```
E NoExec instruction in entry block: 7FFFF75D2890
```
Root cause, as far as we can determine: ThunksDB `Overlay` redirection is only applied in
the host-side rootfs view (the FEXServer mount). pressure-vessel's graphics-library capture
(an x86_64 tool running under FEX) reads the "host" *through* that overlay, so the **guest
thunk stubs get captured byte-for-byte into the container's overrides** as if they were the
real `libvulkan.so.1` / `libwayland-client.so.0`. Inside the container there is no rootfs
mount and no overlay interception, so the guest loads those stub copies as ordinary
libraries from unbless-able paths — the thunk trampolines link, but the invoker region is
never marked executable-for-guest, and the first call through it dies with the NoExec error
above (SIGSEGV, core dumped).
With thunks disabled via `FEX_APP_CONFIG` (ThunksDB all zero) for the entire launch chain,
everything works: pressure-vessel captures the real rootfs libraries, the emulated x86_64
turnip enumerates, and full x86_64 Proton runs Windows games on this device. So the rest of
the stack is fine — the crash is specific to thunk libraries entering the container.
## Environment
- Device: Retroid Pocket 6 (SM8550, Adreno 740), Arch Linux ARM based distro (pocknix-os)
- FEX: 2607, built with thunks (ROCKNIX-lineage packaging; happy to attempt a stock-FEX
repro if useful)
- RootFS: FEX CDN ArchLinux image 2026-01-08 (squashfs, served by FEXServer/squashfuse),
x86 turnip updated to Mesa 26.1.5
- Container: Steam Linux Runtime 4.0 (appid 4183110), launched via `_v2-entry-point`;
pressure-vessel runs in interpreter-root mode (`/run/pressure-vessel/interpreter-root`
is created, srt-bwrap and pv-adverb run under FEX)
- Client: native ARM64 Steam (`steamdeck_publicbeta`), FEX-x86_64/FEX-x86 binfmt_misc
handlers enabled
- ThunksDB config: Vulkan/GL/EGL/drm/WaylandClient/asound = 1, standard `@PREFIX_LIB@`
overlay paths
## Repro
1. ARM64 device with FEX binfmt handlers enabled and a thunk-enabled FEX + rootfs.
2. Install Steam Linux Runtime 4.0 from the native ARM64 Steam client.
3. Run anything Vulkan inside the container, e.g.:
```
~/.local/share/Steam/steamapps/common/SteamLinuxRuntime_4/_v2-entry-point --verb=run -- \
sh -c 'LD_LIBRARY_PATH=/usr/lib/pressure-vessel/overrides/lib/x86_64-linux-gnu vulkaninfo --summary'
```
4. Segfault. With `FEX_SILENTLOG=0 FEX_OUTPUTLOG=stderr`:
```
D LoadLib: libwayland-client -> /usr/lib/fex-emu/HostThunks/libwayland-client-host.so
D LoadLib: libvulkan -> /usr/lib/fex-emu/HostThunks/libvulkan-host.so
E NoExec instruction in entry block: 7FFFF75D2890
Segmentation fault (core dumped)
```
(the faulting address is inside the guest-trampoline/host-invoker range printed by the
preceding `Linking address ... to host invoker ...` lines)
## Diagnostic evidence
- The container's `/usr/lib/pressure-vessel/overrides/lib/x86_64-linux-gnu/libvulkan.so.1`
is **byte-identical to `GuestThunks/libvulkan-guest.so`** (`cmp` inside the container).
Same for the wayland-client capture. The capture files' mtimes equal the GuestThunks
libs' mtimes, not the real libraries'.
- The pv graphics-provider tree (`/var/pressure-vessel/gfx/main/usr/lib/`) contains
`libvulkan.so` / `libvulkan.so.1` as thunk-stub copies, while `libvulkan.so.1.4.335`
(not listed in the ThunksDB overlay) kept the real loader bytes — i.e. exactly the
overlay-listed names were substituted at capture time.
- Adding container-side paths (the overrides path, the gfx-provider path) to the ThunksDB
`Overlay` arrays changes nothing — consistent with overlay interception not existing
in-container (no rootfs mount there; the FEXServer abstract socket crosses the mount
namespace but its mount isn't visible).
- Host-side pieces ARE reachable inside the container: `/usr/lib/fex-emu/HostThunks` is
visible (host thunk libs load — see LoadLib lines above) and `/run/host` exposes the
full host root, including the native aarch64 Vulkan driver.
- Disabling thunks for the whole launch (`FEX_APP_CONFIG` pointing at a ThunksDB-all-zero
json) produces a fully working container: DXVK enumerates the emulated x86 turnip and
x86_64 Proton 11 + SLR runs Windows games end-to-end on this device.
## Asks / suggestions
1. **Graceful failure**: when a guest thunk library is loaded from a path FEX doesn't
recognize (so the invoker pages can't be blessed), fail the library load or fall back
to non-thunked operation instead of segfaulting at first call. Even just a clear log
line would have saved most of this investigation.
2. **Thunks inside containers**: consider recognizing thunk guest libraries by content
(build-id/hash) rather than only by overlay path, or applying overlay redirection
client-side from the ThunksDB config, so thunking can work under pressure-vessel.
The host-side ingredients (`HostThunks`, host driver via `/run/host`) are already
reachable in-container thanks to the interpreter-root integration.
3. Possibly related existing issues: #4639 (Steam break with thunks), #4228 (rootfs
visibility across namespaces).
Happy to provide full logs, the coredump, or test patches on hardware.
Contributor guide
Research direction
Reproduce through _v2-entry-point with the shown pressure-vessel overrides and an enabled ThunksDB Overlay, then inspect the FEXServer rootfs view, /usr/lib/pressure-vessel/overrides, /var/pressure-vessel/gfx/main/usr/lib/, and /usr/lib/fex-emu/HostThunks. Compare behavior with the all-zero FEX_APP_CONFIG case. Done means the container no longer reaches a NoExec segfault: it either handles the guest thunk libraries correctly or reports a clear load failure/fallback.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, linux
- Domain
- backend, operating-systems
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100