AnyPS5/core/libs/prx/libc/include
AlxcBTW b42ef24e07
fix(libs): keep thread_local objects with destructors out of module teardown on Windows (#4029)
* fix(agc): keep the driver's per-thread scratch out of thread_local teardown

With MinGW's emulated TLS, a thread_local with a destructor in a DLL is
destroyed after its storage is gone: when a std::thread ends, winpthread
runs libgcc's emutls key destructor, which frees the thread's thread_local
storage, and only then does the loader's DLL_THREAD_DETACH run the DLL's
tls_atexit list, so the destructors run on freed memory. The queue worker
touches four of them in libSceAgcDriver (the dispatch-ahead map, the
pending waits, the draw-snapshot compare vectors and the image decode
memo), and Driver::stop's join of the worker then corrupts the heap.
Under cdb's checking heap agc_driver_draw_cache_reuse stopped at the
worker's exit with heap corruption in all 127 runs, with graphics
pipeline libraries, with APS5_NO_PIPELINE_LTO=1 and with APS5_NO_GPL=1.
Without it the damage shows intermittently, as exit 0xc0000374 (2 of 143
runs with a cold NVIDIA shader cache) or as a fault in whatever allocates
next, such as NVIDIA's compiler on the optimized-link thread (#2980).

These objects now live in HostThreadLocal, fiber-local storage that owns
them, as the recorder's buffers do since e424b6b7b.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(libs): keep thread_local objects with destructors out of module teardown

The teardown order behind the driver's heap corruption holds in every
module: with MinGW's emulated TLS a thread's thread_local storage is freed
before the module's DLL_THREAD_DETACH runs its thread_local destructors,
so they run on freed objects. PreciseSleepUs's timer (used, among others,
by the video-out vblank thread) then closes a stale handle; libkernel's
directory path, socket waker and UUID random device, libSceRandom's random
device and libScePosixForWebKit's random device and host lookup free or
close stale objects. They move to HostThreadLocal. The other thread_locals
in the modules are trivially destructible or only built for Linux.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(libs): fail when a module registers a thread_local destructor

prx_thread_local_destructors lists the symbols of every built module and,
where MinGW's thread_local destructor support is linked in, disassembles
the module for calls to __cxa_thread_atexit outside libc's registration of
guest destructors. A module that keeps a thread_local with a destructor
fails it with the function that registers one: with main's libSceRandom
it reports sceRandomGetRandomNumber, and with this branch all 122 modules
pass, libc being the only one that links the support.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(agc): keep the image memo behind its pointer

The image decode memo went into HostThreadLocal as the whole array. On
Linux, where HostThreadLocal is a plain thread_local, that put 1024 memo
entries into every thread's TLS block instead of one pointer. It keeps
its unique_ptr as before, now owned by HostThreadLocal, so Linux builds
the same thread_local as main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Dean Galvin <dean.galvin@live.com>
2026-10-12 18:25:29 +13:00
..
exceptions fix(libc): export the C personality to guest code 2026-10-08 13:16:41 +03:00
general fix(libc): write each log line in one call 2026-10-11 13:23:21 -04:00
specifics refactor(libc): define the PROCMAP_QUERY permission flags in HostMapping 2026-10-11 07:44:34 -03:00
ApplicationHeap.hpp feat(libc): implement malloc_usable_size 2026-10-11 04:41:39 +02:00
CpuTopology.hpp perf(agc): pin the queue workers to the performance cores on Linux 2026-10-05 21:23:34 +13:00
CreationMask.hpp fix(libkernel): preserve patched loading and shared-memory object identity 2026-10-11 23:40:46 +02:00
FileStream.hpp fix(libc): fail fgets with a size of 0 or less like FreeBSD 2026-10-11 13:49:43 +00:00
FilesystemError.hpp fix(filesystem): reject invalid parent traversal on Windows 2026-10-12 01:25:02 +05:30
General.hpp fix(filesystem): reject final dot removal paths 2026-10-11 10:42:14 +00:00
GuestAllocations.hpp fix(agc): import GPU-mapped guest memory when it is mapped 2026-10-11 00:23:23 +02:00
GuestArena.hpp fix(libkernel): reserve the AMM ranges below host regions at the top of the guest arena 2026-10-11 17:09:12 +02:00
GuestDirectory.hpp feat(libc): translate guest directory enumeration 2026-09-25 06:41:55 +10:00
GuestHeap.hpp Merge pull request #3213 from Raghav314/fix/libc-heap-without-gpu 2026-10-11 09:14:14 +02:00
GuestLocale.hpp feat(libc): implement collate<char>::_Getcat 2026-10-06 14:53:47 +02:00
GuestStacks.hpp feat(libkernel): implement getcontext, setcontext and makecontext 2026-10-11 13:00:38 +03:00
GuestTime.hpp fix(libc): convert times into the guest's 56-byte tm on Windows 2026-10-10 02:13:17 +02:00
GuestWriteWatch.hpp fix(agc): host imports write-protect only pages a collect already protects 2026-10-10 11:38:28 +05:30
HeapDiagnostics.hpp feat(libc): implement heap trace info 2026-09-27 11:43:36 +03:00
HostEntropy.hpp fix(libs): take guest entropy from the host OS instead of std::random_device 2026-10-11 22:07:49 -03:00
HostThreadLocal.hpp fix(agc): preserve recorder buffers through Windows thread teardown 2026-09-28 09:55:01 +10:00
PreciseWait.hpp fix(libs): keep thread_local objects with destructors out of module teardown on Windows (#4029) 2026-10-12 18:25:29 +13:00
Shutdown.hpp fix(libc): end the process without detach routines in _Exit on Windows 2026-10-10 21:20:29 +13:00
SonyCrt.hpp fix(libs): share Sony CRT semantics between libc and libSceAmpr with tests 2026-10-11 11:42:31 +02:00
WindowsFormatting.hpp Merge pull request #3569 from DariusHQ/fix/libc-format-positional-arguments 2026-10-11 23:40:52 +02:00
WindowsMappings.hpp fix(libc): preserve uncollected shared memory writes on Windows 2026-10-11 16:09:08 -04:00
WindowsScanning.hpp fix(libc): return 0 from scanf when input fails after a suppressed conversion on Windows 2026-10-11 12:12:48 +02:00