You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
libSceFiber: host calls from a 16 KiB fiber overwrite the neighbouring fiber's saved frame (Demon's Souls, segfault at ip 0x1a during level load) #4264
Demon's Souls (PPSA01341 v1.07, US) on Linux crashes during the first level load with segfault at 1a ip 000000000000001a ... error 14 on one of its job threads. Setup: main 7a84b22 with #4049, #758 and #4241 merged locally, Release, ANYPS5_ENABLE_SPIRV_TOOLS=ON, APS5_SPIRV_OPT=none, warm shader cache, RTX 5070 Ti, NVIDIA 595.91.07. It happened about 880 s in, while the title was loading the tutorial level and recompiling compute shaders (recompile 316.9 s over 18400 dispatches).
What the core shows:
The faulting thread's registers match the epilogue of Aps5FiberSwitchStack_nid_no_patch: rsi (the stack being loaded) is 0x26878abd0, rsp is that plus 0x40, and r15, r14, r13, r12, rbx, rbp and rip hold the six words and the return address stored at 0x26878abd8..0x26878ac08. So the thread was switching into a fiber whose saved frame had been overwritten.
The fiber objects in guest memory (magic AP5FIBER) name it: BPE Job Fiber 2 (16 KiB), context 0x268788000+0x4000, savedStack 0x26878abd0, state Running. The title creates its job fibers with 16 KiB contexts placed back to back (0x268784000, 0x268788000, 0x26878c000, ...). There are 64 KiB ones too.
The fiber above it, BPE Job Fiber 3 (16 KiB) (context 0x26878c000+0x4000, Suspended), has stale return addresses on its stack from a call through libSceAgc into Driver::ResolveGraphicsStagesAbi -> PrepareGraphicsStages -> ShaderPreparationTransaction -> ValidateBinaryUsingContextAndValidationState -> ValidateBuiltIns -> ... -> CapabilityPass. Those frames continue below 0x26878c000, into fiber 2's context: CapabilityPass at 0x26878bfe8, ValidationState_t::IsPointerType and ValidateDecorationTarget at 0x26878b348 and 0x26878b358. Fiber 2's own entry frame near the top of its context is gone, and the words around its saved stack pointer are SPIR-V validator locals.
So host code called from fiber 3 used at least 21 KiB of a 16 KiB fiber stack and ran over the saved frame of fiber 2. When a thread later switched to fiber 2, the switch popped validator data into the callee-saved registers and returned to 0x1a.
Cause: guest threads got 1 MiB of host room below their stacks in #2647 (for #2603), but libSceFiber still runs each fiber in the context the guest passed to sceFiberInitialize, so any host call from a fiber has only what is left of that context. Shader preparation with SPIRV-Tools validation goes deeper than 16 KiB. #2456 ran into the same thing with 64 KiB fibers and moved some driver temporaries to the heap, but it was closed by the intake pause, and validation alone needs more than 16 KiB anyway.
A fix is in the PR linked below: fibers run on an mmap'd host stack of the context size plus 1 MiB with a guard page, so host calls get the same 1 MiB of room guest threads have had since #2647. With it, the same run gets past the crash point (the title kept running to t+1209 s). It then stops on a different, unrelated abort: depth export, shader coverage or ordered fragment execution is unsupported (register 0x203 = 0x00000052). That is the stencil reference export bit of DB_SHADER_CONTROL, a separate problem.
Activity