Repository navigation
fix(libkernel): return EINVAL for pthread mutex and cond operations on a destroyed object - #6244
Conversation
|
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.
|
|
Checked on Linux: Ubuntu 26.04 (WSL2), GCC 15.2.0, Release, this head (
Not checked: macOS, the title. AI-assisted: yes (Claude Code). |
|
@adriadam10 a short request for review of this PR. Head AI-assisted (Claude Code). |
|
A title this fixes: Ship of Harkinian (Vulkan) (PPSA99320, catalog 01.000.000), Linux, RTX 4070 Ti, release build, 30 s runs with pad input. Without a ROM, the app opens its menu and quits about 8 s in.
AI-assisted: yes |
…n a destroyed object Locking, trylocking, unlocking a destroyed mutex and signalling, broadcasting, waiting on or destroying a destroyed condition variable threw a C++ exception into the guest. FreeBSD 11.4 libthr returns EINVAL for all of them (thr_mutex.c check_and_init_mutex and mutex_unlock_common compare against THR_MUTEX_DESTROYED, thr_cond.c CHECK_AND_INIT_COND and _pthread_cond_destroy against THR_COND_DESTROYED). The condition wait path already reported EINVAL for a destroyed mutex. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
9284312 to
c664ffb
Compare
Replaces #4971 (closed 14.10. with the note to reopen with a title ID and a log line; GitHub does not let me reopen it). Same branch, same head
9284312ac.What
Locking, trylocking and unlocking a destroyed mutex, and signalling, broadcasting, waiting on or destroying a destroyed condition variable threw a C++ exception into the guest (
Mutex has been destroyed,Condition variable has been destroyed,Condition variable has already been destroyed), which terminates the process. FreeBSD 11.4 libthr returnsEINVALin every one of these cases:thr_mutex.c:check_and_init_mutexreturnsEINVALwhen*m == THR_MUTEX_DESTROYED(lock, timedlock, trylock);mutex_unlock_commonreturnsEINVALfor it;_pthread_mutex_destroyreturnsEINVALfor an already destroyed mutex.thr_cond.c:CHECK_AND_INIT_CONDreturnsEINVALforTHR_COND_DESTROYED(signal, broadcast, wait);_pthread_cond_destroysetsEINVALfor an already destroyed condition variable.The change makes
resolveMutexandresolveCondreport the destroyed state and the callers returnSCE_KERNEL_ERROR_EINVAL(the POSIX wrappers map it toEINVAL). The mutex destroy path and the condition wait path (mutexOwnership) already returnedEINVALfor a destroyed mutex; this makes the rest consistent. Thesce*entry points share these functions, so they change too; I did not check what a PS5 returns there, the choice follows the shared libthr behavior. This includesscePthreadCondSignalto: it now returnsSCE_KERNEL_ERROR_EINVALfor a destroyed condition variable instead of throwing; for a live one it still wakes all waiters (NotifyAll) and still ignores its thread argument, as before. This follows from the code (resolveCondreturns null for a destroyed condition variable); the new test does not callscePthreadCondSignalto.Left as is: NULL pointer arguments still throw (FreeBSD would fault there), as does the use of an uninitialized condition attribute in
scePthreadCondInit.Overlap: #5429 (wake guest mutex waiters on release) is merged (main
d1670009f). It rewrote the same lock call sites inMutex.cpp; the branch now contains a merge commit ofmain(9284312ac) that resolves the conflict there: the three lock paths (pthread_mutex_timedlock'sMutexOperations::Timedlock,scePthreadMutexLock,scePthreadMutexTimedlock) keepacquireResolved(a destroyed mutex answersEINVAL) and hand the resolved mutex to #5429's parking calls (TimedWait::ParkAcquire,TimedWait::AcquireUntil).Cond.cppand the libkernelCMakeLists.txtmerged without a conflict.Title evidence
Ship of Harkinian (PPSA99320), reported by @milescoviello on the previous pull request #4971 (Linux, Ubuntu 24.04, GCC 13.3, Release, RTX 4070 Ti,
maina077a88df+ #6217): with no ROM installed the title shows its "Game files needed" dialog; pressing Cross on its OK button quits the title. Onmain+ #6217 the quit stops withwhat(): Mutex has been destroyed; with the head of this branch the same quit exits with code 0. A run ended by its 75 s timeout stops the same way without the change. I have not run that title myself. The title needs #6217 (malloc_stats_fast) to get that far.Tested
maind92a8dad390af1807cc91622b924252141816a5a+ this branch (clean merge, treedb30968fb):guest_pthread_destroyed_objects(ctest) passes with the change, ctest exit 0; without it (Cond.cppandMutex.cppfrommain, the new test kept, libkernel rebuilt) it fails with test exit code0xc0000409andwhat(): Mutex has been destroyed, ctest exit 8.9284312ac(merge ofmaind1670009finto the previous head6ddb7e5c5): the 27 test executables of the targetsguest_cond_*,guest_mutex_*,guest_posix_sem,guest_pthread_*andguest_semaphoreall exit with code 0.python tools/check_conventions.py --base upstream/mainpasses on this head.maind92a8dad3, Linux, a console, the title itself. The expected values come from the FreeBSD 11.4 sources above, read fromrelease/11.4.0on GitHub.Checklist
main(d92a8dad3) without conflict (the branch contains a merge ofmain; the conflict with the merged perf(libkernel): wake guest mutex waiters on release on Windows #5429 is resolved, see Overlap)NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repositoryAI-assisted (Claude Code).
🤖 Generated with Claude Code