From 3b5dff0f83064e74507673383040363e110ce917 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 14 Dec 2020 18:53:16 -0800 Subject: [PATCH] pm: since 9.0.0, exceptions are signaled only once --- stratosphere/pm/source/impl/pm_process_info.hpp | 8 +++++++- stratosphere/pm/source/impl/pm_process_manager.cpp | 9 +++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/stratosphere/pm/source/impl/pm_process_info.hpp b/stratosphere/pm/source/impl/pm_process_info.hpp index ba7998c8d..8d4ae637a 100644 --- a/stratosphere/pm/source/impl/pm_process_info.hpp +++ b/stratosphere/pm/source/impl/pm_process_info.hpp @@ -35,6 +35,7 @@ namespace ams::pm::impl { Flag_Application = (1 << 6), Flag_SignalOnStart = (1 << 7), Flag_StartedStateChanged = (1 << 8), + Flag_UnhandledException = (1 << 9), }; private: util::IntrusiveListNode list_node; @@ -124,13 +125,18 @@ namespace ams::pm::impl { /* This needs a manual setter, because it sets two flags. */ void SetExceptionOccurred() { this->SetFlag(Flag_ExceptionOccurred); - this->SetFlag(Flag_ExceptionWaitingAttach); + this->SetFlag(Flag_UnhandledException); } DEFINE_FLAG_GET(Has, ExceptionOccurred) DEFINE_FLAG_GET(Has, ExceptionWaitingAttach) + DEFINE_FLAG_GET(Has, UnhandledException) + + DEFINE_FLAG_SET(ExceptionWaitingAttach) + DEFINE_FLAG_CLEAR(ExceptionOccurred) DEFINE_FLAG_CLEAR(ExceptionWaitingAttach) + DEFINE_FLAG_CLEAR(UnhandledException) DEFINE_FLAG_SET(SignalOnDebugEvent) DEFINE_FLAG_GET(Should, SignalOnDebugEvent) diff --git a/stratosphere/pm/source/impl/pm_process_manager.cpp b/stratosphere/pm/source/impl/pm_process_manager.cpp index 7a761817a..200dfd4bf 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.cpp +++ b/stratosphere/pm/source/impl/pm_process_manager.cpp @@ -343,10 +343,14 @@ namespace ams::pm::impl { process_info->ClearSignalOnStart(); os::SignalSystemEvent(std::addressof(g_process_event)); } + process_info->ClearUnhandledException(); break; case svc::ProcessState_Crashed: - process_info->SetExceptionOccurred(); - os::SignalSystemEvent(std::addressof(g_process_event)); + if (!process_info->HasUnhandledException()) { + process_info->SetExceptionOccurred(); + os::SignalSystemEvent(std::addressof(g_process_event)); + } + process_info->SetExceptionWaitingAttach(); break; case svc::ProcessState_RunningAttached: if (process_info->ShouldSignalOnDebugEvent()) { @@ -354,6 +358,7 @@ namespace ams::pm::impl { process_info->SetSuspendedStateChanged(); os::SignalSystemEvent(std::addressof(g_process_event)); } + process_info->ClearUnhandledException(); break; case svc::ProcessState_Terminated: /* Free process resources, unlink from waitable manager. */