mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-29 16:51:20 +00:00
fix(libc): run thread-local destructors
Why: Thread-atexit registrations were discarded, leaving objects alive after their guest TLS storage was released. What: Store registrations per host thread and run them in LIFO order before pthread keys and guest TLS are destroyed. Why safe: Only callbacks registered on the exiting thread run, once, before existing teardown continues.
This commit is contained in:
1 parent
43f30d3ab2
commit
ed84370786
2 files changed
+30
-11
No files matched your search
@@ -65,6 +65,10 @@
|
|||||||
|
|
||||||
namespace Libs {
|
namespace Libs {
|
||||||
|
|
||||||
|
namespace LibcInternalExt {
|
||||||
|
void RunThreadAtexitDestructors();
|
||||||
|
} // namespace LibcInternalExt
|
||||||
|
|
||||||
namespace LibKernel {
|
namespace LibKernel {
|
||||||
|
|
||||||
LIB_NAME("libkernel", "libkernel");
|
LIB_NAME("libkernel", "libkernel");
|
||||||
@@ -3347,6 +3351,8 @@ int PthreadGetCurrentPriorityForKernel() {
|
|||||||
static void CleanupThread(void* arg) {
|
static void CleanupThread(void* arg) {
|
||||||
auto* thread = static_cast<Pthread>(arg);
|
auto* thread = static_cast<Pthread>(arg);
|
||||||
|
|
||||||
|
LibcInternalExt::RunThreadAtexitDestructors();
|
||||||
|
|
||||||
auto thread_dtors = g_pthread_context->GetThreadDtors();
|
auto thread_dtors = g_pthread_context->GetThreadDtors();
|
||||||
|
|
||||||
if (thread_dtors != nullptr) {
|
if (thread_dtors != nullptr) {
|
||||||
|
|||||||
+24
-11
@@ -633,6 +633,15 @@ LIB_VERSION("LibcInternalExt", 1, "LibcInternal", 1, 1);
|
|||||||
static uint64_t g_mspace_atomic_id_mask = 0;
|
static uint64_t g_mspace_atomic_id_mask = 0;
|
||||||
static uint64_t g_mstate_table[64] = {0};
|
static uint64_t g_mstate_table[64] = {0};
|
||||||
|
|
||||||
|
using thread_atexit_destructor_t = KYTY_SYSV_ABI void (*)(void*);
|
||||||
|
|
||||||
|
struct ThreadAtexitDestructor {
|
||||||
|
thread_atexit_destructor_t destructor;
|
||||||
|
void* object;
|
||||||
|
};
|
||||||
|
|
||||||
|
static thread_local std::vector<ThreadAtexitDestructor> g_thread_atexit_destructors;
|
||||||
|
|
||||||
struct Info {
|
struct Info {
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
uint32_t unknown1;
|
uint32_t unknown1;
|
||||||
@@ -650,25 +659,29 @@ void KYTY_SYSV_ABI LibcHeapGetTraceInfo(Info* info) {
|
|||||||
info->mstate_table = g_mstate_table;
|
info->mstate_table = g_mstate_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t KYTY_SYSV_ABI LibcInternalExtUnknownQBS714Jr3g(uint64_t arg0, uint64_t arg1, uint64_t arg2,
|
int KYTY_SYSV_ABI LibcInternalExtCxaThreadAtexit(thread_atexit_destructor_t destructor, void* object,
|
||||||
uint64_t arg3, uint64_t arg4,
|
void* /*module_id*/) {
|
||||||
uint64_t arg5) {
|
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
LOGF("\t arg0 = 0x%016" PRIx64 "\n"
|
g_thread_atexit_destructors.push_back({destructor, object});
|
||||||
"\t arg1 = 0x%016" PRIx64 "\n"
|
|
||||||
"\t arg2 = 0x%016" PRIx64 "\n"
|
|
||||||
"\t arg3 = 0x%016" PRIx64 "\n"
|
|
||||||
"\t arg4 = 0x%016" PRIx64 "\n"
|
|
||||||
"\t arg5 = 0x%016" PRIx64 "\n",
|
|
||||||
arg0, arg1, arg2, arg3, arg4, arg5);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RunThreadAtexitDestructors() {
|
||||||
|
while (!g_thread_atexit_destructors.empty()) {
|
||||||
|
auto destructor = g_thread_atexit_destructors.back();
|
||||||
|
g_thread_atexit_destructors.pop_back();
|
||||||
|
|
||||||
|
if (destructor.destructor != nullptr) {
|
||||||
|
destructor.destructor(destructor.object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LIB_DEFINE(InitLibcInternalExt_1) {
|
LIB_DEFINE(InitLibcInternalExt_1) {
|
||||||
LIB_FUNC("NWtTN10cJzE", LibcInternalExt::LibcHeapGetTraceInfo);
|
LIB_FUNC("NWtTN10cJzE", LibcInternalExt::LibcHeapGetTraceInfo);
|
||||||
LIB_FUNC("qBS714-Jr3g", LibcInternalExt::LibcInternalExtUnknownQBS714Jr3g);
|
LIB_FUNC("qBS714-Jr3g", LibcInternalExt::LibcInternalExtCxaThreadAtexit);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LibcInternalExt
|
} // namespace LibcInternalExt
|
||||||
|
|||||||
Reference in new issue
Block a user