From f83698cb506352cc6a6fcc61b835fa81bd6d7381 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Mon, 11 Jan 2021 09:01:06 -0800 Subject: [PATCH 1/2] Uninstalls SignalDelegator signals on destruction Tear this down earlier so if we catch a signal on shutdown then we don't crash in the handler. Fixes some pain around debugging shutdown crashes --- Source/Tests/ELFLoader.cpp | 2 ++ Source/Tests/LinuxSyscalls/SignalDelegator.cpp | 15 +++++++++++++++ Source/Tests/LinuxSyscalls/SignalDelegator.h | 1 + 3 files changed, 18 insertions(+) diff --git a/Source/Tests/ELFLoader.cpp b/Source/Tests/ELFLoader.cpp index 30274d940..070e02935 100644 --- a/Source/Tests/ELFLoader.cpp +++ b/Source/Tests/ELFLoader.cpp @@ -277,6 +277,8 @@ int main(int argc, char **argv, char **const envp) { auto ProgramStatus = FEXCore::Context::GetProgramStatus(CTX); + SyscallHandler.reset(); + SignalDelegation.reset(); FEXCore::Context::DestroyContext(CTX); FEXCore::Config::Shutdown(); diff --git a/Source/Tests/LinuxSyscalls/SignalDelegator.cpp b/Source/Tests/LinuxSyscalls/SignalDelegator.cpp index 8dcfce088..fadfbf08d 100644 --- a/Source/Tests/LinuxSyscalls/SignalDelegator.cpp +++ b/Source/Tests/LinuxSyscalls/SignalDelegator.cpp @@ -317,6 +317,21 @@ namespace FEX::HLE { } } + SignalDelegator::~SignalDelegator() { + for (int i = 0; i < MAX_SIGNALS; ++i) { + if (i == 0 || + i == SIGKILL || + i == SIGSTOP || + !HostHandlers[i].Installed + ) { + continue; + } + sigaction(i, &HostHandlers[i].OldAction, nullptr); + HostHandlers[i].Installed = false; + } + GlobalDelegator = nullptr; + } + void SignalDelegator::RegisterTLSState(FEXCore::Core::InternalThreadState *Thread) { ThreadData.Thread = Thread; diff --git a/Source/Tests/LinuxSyscalls/SignalDelegator.h b/Source/Tests/LinuxSyscalls/SignalDelegator.h index bd315cdac..512e0c9c3 100644 --- a/Source/Tests/LinuxSyscalls/SignalDelegator.h +++ b/Source/Tests/LinuxSyscalls/SignalDelegator.h @@ -22,6 +22,7 @@ namespace FEX::HLE { // Returns true if the host handled the signal // Arguments are the same as sigaction handler SignalDelegator(); + virtual ~SignalDelegator(); /** * @brief Registers an emulated thread's object to a TLS object From aa3b77e4c83bffcd571ad356e5fb366d2a932dcd Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Mon, 11 Jan 2021 09:03:56 -0800 Subject: [PATCH 2/2] Uninstalls LogManager handlers on shutdown In case something manages to have stayed alive and tried throwing a message, this will no longer crash. Noticed this with the previous commit --- External/FEXCore/Source/Utils/LogManager.cpp | 2 ++ External/FEXCore/include/FEXCore/Utils/LogManager.h | 2 ++ Source/Tests/ELFLoader.cpp | 3 +++ 3 files changed, 7 insertions(+) diff --git a/External/FEXCore/Source/Utils/LogManager.cpp b/External/FEXCore/Source/Utils/LogManager.cpp index 36174cc26..842c7bae9 100644 --- a/External/FEXCore/Source/Utils/LogManager.cpp +++ b/External/FEXCore/Source/Utils/LogManager.cpp @@ -7,6 +7,7 @@ namespace LogMan { namespace Throw { std::vector Handlers; void InstallHandler(ThrowHandler Handler) { Handlers.emplace_back(Handler); } +void UnInstallHandlers() { Handlers.clear(); } [[noreturn]] void M(const char *fmt, va_list args) { size_t MsgSize = 1024; @@ -30,6 +31,7 @@ void InstallHandler(ThrowHandler Handler) { Handlers.emplace_back(Handler); } namespace Msg { std::vector Handlers; void InstallHandler(MsgHandler Handler) { Handlers.emplace_back(Handler); } +void UnInstallHandlers() { Handlers.clear(); } void M(DebugLevels Level, const char *fmt, va_list args) { size_t MsgSize = 1024; diff --git a/External/FEXCore/include/FEXCore/Utils/LogManager.h b/External/FEXCore/include/FEXCore/Utils/LogManager.h index 20fcc8337..ab8b3e09f 100644 --- a/External/FEXCore/include/FEXCore/Utils/LogManager.h +++ b/External/FEXCore/include/FEXCore/Utils/LogManager.h @@ -19,6 +19,7 @@ constexpr DebugLevels MSG_LEVEL = INFO; namespace Throw { using ThrowHandler = void(*)(char const *Message); void InstallHandler(ThrowHandler Handler); +void UnInstallHandlers(); [[noreturn]] void M(const char *fmt, va_list args); @@ -40,6 +41,7 @@ static inline void A(bool, const char*, ...) {} namespace Msg { using MsgHandler = void(*)(DebugLevels Level, char const *Message); void InstallHandler(MsgHandler Handler); +void UnInstallHandlers(); void M(DebugLevels Level, const char *fmt, va_list args); diff --git a/Source/Tests/ELFLoader.cpp b/Source/Tests/ELFLoader.cpp index 070e02935..73ff00fe4 100644 --- a/Source/Tests/ELFLoader.cpp +++ b/Source/Tests/ELFLoader.cpp @@ -283,6 +283,9 @@ int main(int argc, char **argv, char **const envp) { FEXCore::Config::Shutdown(); + LogMan::Throw::UnInstallHandlers(); + LogMan::Msg::UnInstallHandlers(); + if (OutputFD != stderr && OutputFD != stdout && OutputFD != nullptr) {