diff --git a/FEXCore/Source/Interface/Context/Context.h b/FEXCore/Source/Interface/Context/Context.h index c9c5da72a..221074bdb 100644 --- a/FEXCore/Source/Interface/Context/Context.h +++ b/FEXCore/Source/Interface/Context/Context.h @@ -254,7 +254,6 @@ namespace FEXCore::Context { FEXCore::Core::InternalThreadState* ParentThread{}; fextl::vector Threads; std::atomic_bool CoreShuttingDown{false}; - bool NeedToCheckXID{true}; std::mutex IdleWaitMutex; std::condition_variable IdleWaitCV; diff --git a/FEXCore/Source/Interface/Core/Core.cpp b/FEXCore/Source/Interface/Core/Core.cpp index 7c09d7831..ce2ac2a5c 100644 --- a/FEXCore/Source/Interface/Core/Core.cpp +++ b/FEXCore/Source/Interface/Core/Core.cpp @@ -530,21 +530,10 @@ namespace FEXCore::Context { ExecutionThreadHandler *Arg = reinterpret_cast(FEXCore::Allocator::malloc(sizeof(ExecutionThreadHandler))); Arg->This = this; Arg->Thread = Thread; - Thread->StartPaused = NeedToCheckXID; Thread->ExecutionThread = FEXCore::Threads::Thread::Create(ThreadHandler, Arg); // Wait for the thread to have started Thread->ThreadWaiting.Wait(); - - if (NeedToCheckXID) { - // The first time an application creates a thread, GLIBC installs their SETXID signal handler. - // FEX needs to capture all signals and defer them to the guest. - // Once FEX creates its first guest thread, overwrite the GLIBC SETXID handler *again* to ensure - // FEX maintains control of the signal handler on this signal. - NeedToCheckXID = false; - SignalDelegation->CheckXIDHandler(); - Thread->StartRunning.NotifyAll(); - } } void ContextImpl::InitializeThreadTLSData(FEXCore::Core::InternalThreadState *Thread) { diff --git a/FEXCore/include/FEXCore/Core/SignalDelegator.h b/FEXCore/include/FEXCore/Core/SignalDelegator.h index 85cb0cccd..5b9fe8826 100644 --- a/FEXCore/include/FEXCore/Core/SignalDelegator.h +++ b/FEXCore/include/FEXCore/Core/SignalDelegator.h @@ -47,14 +47,6 @@ namespace Core { virtual void RegisterTLSState(FEXCore::Core::InternalThreadState *Thread) = 0; virtual void UninstallTLSState(FEXCore::Core::InternalThreadState *Thread) = 0; - /** - * @brief Check to ensure the XID handler is still set to the FEX handler - * - * On a new thread GLIBC will set the XID handler underneath us. - * After the first thread is created check this. - */ - virtual void CheckXIDHandler() = 0; - struct SignalDelegatorConfig { bool StaticRegisterAllocation{}; bool SupportsAVX{}; diff --git a/Source/Tools/CommonTools/DummyHandlers.h b/Source/Tools/CommonTools/DummyHandlers.h index a7c4bd6c6..6c2428c60 100644 --- a/Source/Tools/CommonTools/DummyHandlers.h +++ b/Source/Tools/CommonTools/DummyHandlers.h @@ -25,8 +25,6 @@ class DummySyscallHandler: public FEXCore::HLE::SyscallHandler, public FEXCore:: class DummySignalDelegator final : public FEXCore::SignalDelegator, public FEXCore::Allocator::FEXAllocOperators { public: - void CheckXIDHandler() override {} - void SignalThread(FEXCore::Core::InternalThreadState *Thread, FEXCore::Core::SignalEvent Event) override {} FEXCore::Core::InternalThreadState *GetBackingTLSThread() { diff --git a/Source/Tools/FEXLoader/LinuxSyscalls/SignalDelegator.h b/Source/Tools/FEXLoader/LinuxSyscalls/SignalDelegator.h index 3c81ae3d6..af1e23d97 100644 --- a/Source/Tools/FEXLoader/LinuxSyscalls/SignalDelegator.h +++ b/Source/Tools/FEXLoader/LinuxSyscalls/SignalDelegator.h @@ -89,7 +89,13 @@ namespace FEX::HLE { uint64_t GuestSignalFD(int fd, const uint64_t *set, size_t sigsetsize , int flags); /** @} */ - void CheckXIDHandler() override; + /** + * @brief Check to ensure the XID handler is still set to the FEX handler + * + * On a new thread GLIBC will set the XID handler underneath us. + * After the first thread is created check this. + */ + void CheckXIDHandler(); void UninstallHostHandler(int Signal); FEXCore::Context::Context *CTX; diff --git a/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls.h b/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls.h index 11de00ee8..afddc2a85 100644 --- a/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls.h +++ b/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls.h @@ -225,6 +225,9 @@ public: SourcecodeResolver *GetSourcecodeResolver() override { return this; } + bool NeedXIDCheck() const { return NeedToCheckXID; } + void DisableXIDCheck() { NeedToCheckXID = false; } + protected: SyscallHandler(FEXCore::Context::Context *_CTX, FEX::HLE::SignalDelegator *_SignalDelegation); @@ -250,6 +253,7 @@ private: std::mutex FutexMutex; std::mutex SyscallMutex; FEXCore::CodeLoader *LocalLoader{}; + bool NeedToCheckXID{true}; #ifdef DEBUG_STRACE void Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret); diff --git a/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls/Thread.cpp b/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls/Thread.cpp index 22f8adcd4..fd08ca73c 100644 --- a/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls/Thread.cpp +++ b/Source/Tools/FEXLoader/LinuxSyscalls/Syscalls/Thread.cpp @@ -59,8 +59,19 @@ namespace FEX::HLE { } auto NewThread = CTX->CreateThread(0, 0, &NewThreadState, args->args.parent_tid); + bool NeedsXIDCheck = FEX::HLE::_SyscallHandler->NeedXIDCheck(); + NewThread->StartPaused = NeedsXIDCheck; CTX->InitializeThread(NewThread); + if (NeedsXIDCheck) { + // The first time an application creates a thread, GLIBC installs their SETXID signal handler. + // FEX needs to capture all signals and defer them to the guest. + // Once FEX creates its first guest thread, overwrite the GLIBC SETXID handler *again* to ensure + // FEX maintains control of the signal handler on this signal. + FEX::HLE::_SyscallHandler->GetSignalDelegator()->CheckXIDHandler(); + FEX::HLE::_SyscallHandler->DisableXIDCheck(); + } + if (FEX::HLE::_SyscallHandler->Is64BitMode()) { if (flags & CLONE_SETTLS) { x64::SetThreadArea(NewThread->CurrentFrame, reinterpret_cast(args->args.tls));