Repository navigation
fix(libkernel): keep host fault signals available on macOS - #8477
oneandonlydean merged 6 commits into
Conversation
Rosetta may swallow or retry write-watch faults when a guest thread inherits a blocked host SIGBUS or SIGSEGV mask. Keep synchronous fault signals deliverable during thread creation and after startup while preserving the creator mask. Add a macOS regression test for both behaviors. Based on Cloud-Multiplayer’s write-watch investigation in boykopovar#1.
Keep the focused host-signal change current with main while preserving its one-topic diff.
|
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.
|
|
Ran the new test standalone on Apple silicon, since the description says it could not run on this branch alone. Machine: Apple M4 Pro (24 GB), macOS 27.0.1 (26A434), x86-64 under Rosetta 2, Apple clang 21.0.0, CMake 4.4.4, Ninja 1.13.2, Release, Base: main does not build the libraries on macOS, so I used mugurc's
The 17 fail without the fix too (and again when rerun one by one with it), so they come from the base, not from this change. The 17 failures common to both runs
Not checked: a title with and without the fix (Planet of Lana stops on this base at a pixel shader that reads barycentrics, before any write-watch path matters), Linux and Windows (the change is AI-assisted: yes |
|
A title that needs this fix: Stray (PPSA02100, v01.002.000, Unreal Engine 4) hangs twice on macOS without it, and gets past both with only f22b570 added. Machine: Apple M4 Pro (24 GB), macOS 27.0.1, x86-64 under Rosetta 2, MoltenVK 1.4.2 (Vulkan SDK 1.4.363.0).
Both hangs are a plain store to a write-watched page that never returns, which is what the description explains: the threads inherit a mask with Not checked: the depth bounds stop and anything after it, Linux and Windows, the full CTest suite. AI-assisted: yes |
Tested on Apple M1 Pro, macOS 27.0.1 (x86_64 build under Rosetta 2)Applied at
AI-assisted: yes (Claude Code applied the PR, ran the tests and wrote this report). |
|
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) |
Keep the focused host-signal change reviewable against current main while preserving the upstream thread and test changes. The standalone macOS build still depends on the macOS libc foundation.
Tested on Apple M1 Pro, macOS 27.0.1 (x86_64 build under Rosetta 2)Retest at Applied at
AI-assisted: yes (Claude Code applied the PR, ran the tests and wrote this report). |
jotitadev
left a comment
There was a problem hiding this comment.
Tested head fc9716dad merged with current main on macOS. The fix works, but after the merge the PR's test makes public_headers fail.
Machine: Apple M2 Max (32 GB), macOS 27.2 (26B5112a), Apple clang 21.0.0, x86_64 Release under Rosetta 2 (-DCMAKE_OSX_ARCHITECTURES=x86_64, Ninja, BUILD_TESTING=ON, Python 3.9 from Xcode).
Base: main b986c11a34 does not build the libraries on macOS by itself, so the tree is that main plus the open macOS build PRs (#10366, #7631, #10659, #10660, #11249, #11358, #10669, #10552, #7804, #10676, #11447, #11437) and #11554, plus #11705 (applied locally). Only this PR is toggled, with git merge --no-commit on top.
GuestPthreadHostFaultMask.cpp declares scePthreadCreate and scePthreadJoin itself. Since 35cf8d5 (canonical headers, 2026-10-24, after this branch's last main merge 137a8fab89), core/libs/prx/libkernel/include/Api.hpp declares both, and the public_headers audit allows only one declaration:
scePthreadCreate: expected exactly one header declaration; found 2: core/libs/prx/libkernel/include/Api.hpp:559, core/libs/tests/GuestPthreadHostFaultMask.cpp:7
scePthreadJoin: expected exactly one header declaration; found 2: core/libs/prx/libkernel/include/Api.hpp:560, core/libs/tests/GuestPthreadHostFaultMask.cpp:8
The audit reads the source tree, so it should fail on every host, not only macOS. #9263 hit the same thing after it merged, and main fixed it in 039408c. The same change works here:
+#include "prx/libkernel/include/Api.hpp"
#include "SceTypes.hpp"
#include <csignal>
#include <cstdlib>
#include <pthread.h>
-extern "C" {
-int APS5_VABI scePthreadCreate(Pthread* thread, const PthreadAttr* attr, PthreadEntry entry, void* arg, const char* name);
-int APS5_VABI scePthreadJoin(Pthread thread, void** retval);
-}With that change, public_headers and the 64 public_headers_compile_* batches pass (65/65), and guest_pthread_host_fault_mask passes 3/3. I ran this in the tree above with this PR, #10876 and #9263 (plus 039408c) merged together, and in that tree the non-GPU suite (1374 tests) has no new failures against the base apart from the 65 public_headers* tests, which pass with the change. The merge itself is clean.
Written with AI assistance (Claude Code). I ran the builds and tests above on my machine.
The public header audit now finds duplicate declarations when this test redeclares the pthread APIs. Include the canonical libkernel header so the test follows the current API and public_headers remains valid.
Update the host-fault signal change to current main while preserving the Windows pending-exception delivery path and macOS unblocked fault signals.
What
Keep synchronous host fault signals deliverable while
scePthreadCreatecreates a guest thread, and unblock them when the guest thread starts on macOS. The guest signal mask remains emulated by libkernel. This prevents a guest-created thread under Rosetta from inheriting a host mask that hidesSIGBUS/SIGSEGVwrite-watch faults.The focused test checks that the creator's host mask is restored and the guest worker can receive fault signals. This extracts the issue #1 finding by @Cloud-Multiplayer from the former integration PR #7332. No title run is claimed for this branch.
Tested
mainthroughf2d874c1fdinadefe80eea; resolved theThread.cppconflict while preserving both Windows pending-exception delivery and the macOS fault-signal mask behavior.python3 tools/check_conventions.py --base origin/main: passed.ctest --test-dir build-mac -R '^public_headers$' -j1 --output-on-failure: passed.mainremains blocked by existing host portability gaps:pthread_getattr_npandpthread_getcpuclockidinThread.cpp,st_atim/st_mtim/st_ctiminNativeStat.cpp,MFD_CLOEXECinSharedMemory.cpp, andsys/vfs.hinStdio.cpp. These errors prevent building the focused test on this base; the test has not been rerun locally after the merge.Checklist
main; no other open PR implements the same functions.mdfiles or images added to the repository