Repository navigation
fix(libkernel): report unwind information for guest and host addresses on macOS - #9263
Conversation
…s on macOS Two unwind queries a title makes went wrong on macOS, so a C++ exception the title would catch ended the process instead: God of War Sons of Sparta (PPSA28997) stops on an IL2CPP exception it normally handles. - sceKernelGetModuleInfoForUnwind found a relinked image and its PT_GNU_EH_FRAME header but left eh_frame_addr and eh_frame_size at zero, so the title's unwinder found no FDE for its own frame. The tables are now read with EhFrame::ReadTables over the image's load segments, as ModuleInfo does on Linux, and eh_frame_size includes the zero terminator, as on Linux. - sceSysmoduleGetModuleInfoForUnwind read /proc/self/maps outside Windows and threw on every call on macOS. It now answers from mach_vm_region, with the image path from dladdr, as the Linux branch answers from the mapping. guest_unwind_module_info now runs on macOS: the test executable carries the __APS5DATA,__meta program headers that the macOS dl_iterate_phdr reads from a relinked image. guest_sysmodule checks the macOS answers against mach_vm_region. Co-authored-by: mugurc <mceker@gmail.com>
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
SummaryVampire Survivors (PPSA21703, 01.016.107) does not get past startup on macOS with main + #8658 alone: a managed exception that the game catches on the console escapes and the process terminates. With #9263 merged on top, the same converted game boots, initializes PSN, mounts its save data and presents frames for 60 s (and for the 10 minute plays I did), and exits cleanly. SetupApple M2 16 GB, macOS 27.2, Rosetta 2, MoltenVK 1.4.2 (Vulkan SDK 1.4.363). Tree: main at d6e7ab4 + #8658 (merge) = integ/macos-8658; second tree = that + #9263 head (bfa5368) merged. Both built with Result| tree | exit | "[PS5Account] PSN Initialized" | SaveData mount | frames | How I located it
Notes
|
|
Thanks for testing it on another title and machine, and for the detailed write-up. It matches what the PR fixes: without unwind information for relinked images, the guest unwinder cannot find the landing pad and the exception that the game catches on the console escapes. I have added PPSA21703 to the Unblocks line. |
|
Tested on an Apple M2 Pro, macOS, x86_64 Release under Rosetta 2, MoltenVK 1.4.2, applied on top of #8658's
AI-assisted: yes (Cana) |
What
On macOS a C++ exception that a title throws and catches itself can end the process: two unwind queries the title's own unwinder makes give it nothing to work with.
sceKernelGetModuleInfoForUnwindfound the relinked image and itsPT_GNU_EH_FRAMEheader, but lefteh_frame_addrandeh_frame_sizeat zero, so the title's unwinder found no FDE for its own frames. The tables are now read withEhFrame::ReadTablesover the image's load segments, asModuleInfodoes on Linux.eh_frame_sizeincludes the zero terminator, as on Linux and as the existing debt entry records for firmware 13.60.sceSysmoduleGetModuleInfoForUnwindread/proc/self/mapseverywhere except Windows, so on macOS every call threw (failed to open /proc/self/maps). It now answers frommach_vm_region, with the image path fromdladdr, as the Linux branch answers from the mapping.Every library change is behind
__APPLE__. The only line that changes on Linux and Windows is inGuestSysmodule.cpp:CheckUnwindInfo()is now called on every host, because macOS gets its own variant.Carried over from #7332/#8481, which the open-PR limit closed.
Overlap: #7201 contains the same
eh_frameread inside its macOS port; its review asks for that PR to be split into topics, and this is the unwind piece, plus the sysmodule fix #7201 does not have.Tested
Current
main(2026-10-26): I looked for the smallest set of open PRs that boots titles on macOS frommain035ac96edd: #10366, #10552, #7631, #7804, #11249, #10669, #10540, #11447, #11047, #11048, #10876 and this PR, plus a localVulkanDevice.cpppatch that no open PR covers yet. With it, Planet of Lana and God of War Sons of Sparta, relinked with that tree, start from New Game and run without errors (Lana in gameplay for 120 s, GoW to the Cyclops fight in 145 s). Without this PR, Lana still runs, but GoW stops withTerminating due to uncaught exception of type Il2CppExceptionWrapper.Machine: Apple M4 Pro (24 GB), macOS 27.0.1, x86-64 under Rosetta 2, Apple clang 21.0.0.
maindoes not build the libraries on macOS by itself, so everything ran on top of #8658 (0a6c0fd) with #9193 and the macOSRTLD_GLOBALloader change from #7332 (2d500a0), which FMOD titles need to load at all.guest_unwind_module_info(new on macOS): the test executable carries the__APS5DATA,__metaprogram headers that the macOSdl_iterate_phdrreads from a relinked image. It checks the header and frame addresses, a one-record and a two-record table (sizes 20 and 36, terminator included), an image withoutPT_GNU_EH_FRAME(all zero), and a table whose terminator lies outside the load segment (throws). Passes; withModule.cppfrommainit fails ("wrong EH frame address").guest_sysmodule(macOS variant ofCheckUnwindInfo): a function in the test executable, one in the library, an anonymous page (empty name) and an unmapped address (throws), checked againstmach_vm_regionanddladdr. Passes; withExport.cppfrommainit aborts.guest_dynamic_loader,guest_dynamic_loader_variant_names,unwind_record_bounds,unwind_callback_abi_*.Terminating due to uncaught exception of type Il2CppExceptionWrapper; the managed exception, read fromsceKernelDebugWriteCppExceptionInfowith a local log line, isFMODUnity.BusNotFoundException, which the title normally catches. Without only the sysmodule part it stops withlibc++abi: terminating due to uncaught exception of type std::runtime_error: sceSysmoduleGetModuleInfoForUnwind: failed to open /proc/self/maps. With both it opens its 38 FMOD banks and plays through to the Cyclops fight (27.0 fps in the fight, frame dumps checked).python3 tools/check_conventions.py --base origin/main: all checks pass.Not tested: Linux and Windows builds (no library change there), the full CTest suite.
Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)