diff --git a/Source/Debug/Debug.hpp b/Source/Debug/Debug.hpp index c5e51e69..bafca4d0 100644 --- a/Source/Debug/Debug.hpp +++ b/Source/Debug/Debug.hpp @@ -33,6 +33,6 @@ namespace Aurora::Debug AuUInt32 ReportStackTrace(const StackTrace &trace, const AuString &message); void CheckErrors(); - void PlatformHandleFatal(bool fatal); + void PlatformHandleFatal(bool fatal, bool bNoExit = false); void InitDebug(); } diff --git a/Source/Debug/ExceptionWatcher.NT.cpp b/Source/Debug/ExceptionWatcher.NT.cpp index bae12978..f5f1d6e0 100644 --- a/Source/Debug/ExceptionWatcher.NT.cpp +++ b/Source/Debug/ExceptionWatcher.NT.cpp @@ -176,7 +176,7 @@ namespace Aurora::Debug #endif } - void PlatformHandleFatal(bool fatal) + void PlatformHandleFatal(bool fatal, bool bNoExit) { static bool forceFail {false}; _EXCEPTION_POINTERS ptrs; @@ -191,9 +191,12 @@ namespace Aurora::Debug Debug::Panic(); } - if (!AuExchange(forceFail, true)) + if (!bNoExit) { - Exit::PostLevel(AuThreads::GetThread(), Aurora::Exit::ETriggerLevel::eFatalException); + if (!AuExchange(forceFail, true)) + { + Exit::PostLevel(AuThreads::GetThread(), Exit::ETriggerLevel::eFatalException); + } } ex.ExceptionCode = 0x1337; diff --git a/Source/Debug/ExceptionWatcher.Win32.cpp b/Source/Debug/ExceptionWatcher.Win32.cpp index 0ffe3631..133ab830 100644 --- a/Source/Debug/ExceptionWatcher.Win32.cpp +++ b/Source/Debug/ExceptionWatcher.Win32.cpp @@ -201,6 +201,7 @@ namespace Aurora::Debug } }; + StackTrace backtrace; { static bool bRunOnce {}; struct ArrowEx : Grug::Arrow @@ -219,46 +220,75 @@ namespace Aurora::Debug PlatformHandleFatal(true); } - StackTrace backtrace; ParseStack(ExceptionInfo->ContextRecord, backtrace); - - #if defined(AU_CFG_ID_INTERNAL) || defined(AU_CFG_ID_DEBUG) - const bool kShouldPrintErrors = true; - #else - const bool kShouldPrintErrors = false; - #endif - - if (pThrowInfo) - { - ReportSEH(handle, exception, pThrowInfo, handleNoCppObject, backtrace, [&](const AuString &str) - { - // Pre-submit callback -> its showtime - if ((isCritical || kShouldPrintErrors) && (minimal == 0)) - { - if (gRuntimeConfig.debug.bPrintExceptionStackTracesOut) - { - AuLogWarn("NT Exception: 0x{:x}, {}", ExceptionInfo->ExceptionRecord->ExceptionCode, str); - AuLogWarn("{}", StringifyStackTrace(backtrace)); - } - } - }); - } } catch (...) { } + }; + + empty.pCallback =[](Grug::Arrow *pBase) -> void + { + auto pEx = (ArrowEx *)pBase; + pEx->callback(); + }; + + Grug::HurlArrow(&empty, empty.pCallback, {}); + Grug::ArrowWait(&empty); + } + + AuVoidFunc doReportLocal; + { + + #if defined(AU_CFG_ID_INTERNAL) || defined(AU_CFG_ID_DEBUG) + const bool kShouldPrintErrors = true; + #else + const bool kShouldPrintErrors = false; + #endif + + doReportLocal = [&]() + { + if (pThrowInfo) + { + ReportSEH(handle, exception, pThrowInfo, handleNoCppObject, backtrace, [&](const AuString &str) + { + // Pre-submit callback -> its showtime + if ((isCritical || kShouldPrintErrors) && (minimal == 0)) + { + if (gRuntimeConfig.debug.bPrintExceptionStackTracesOut) + { + AuLogWarn("NT Exception: 0x{:x}, {}", ExceptionInfo->ExceptionRecord->ExceptionCode, str); + AuLogWarn("{}", StringifyStackTrace(backtrace)); + } + } + }); + } + }; + doReportLocal(); + } + + auto pThread = AuThreads::GetThread(); + + { + static bool bRunOnce {}; + struct ArrowEx : Grug::Arrow + { + AuFunction callback; + }; + ArrowEx empty; + + empty.callback = [&]() + { + doReportLocal(); + + Exit::PostLevel(pThread, Aurora::Exit::ETriggerLevel::eFatalException); try { - if (isCritical) - { - Telemetry::Mayday(); - } - if (isCritical || gRuntimeConfig.debug.bIsExceptionThrowFatal) // exception = literally anything { - PlatformHandleFatal(true); + PlatformHandleFatal(true, true); } } catch (...) diff --git a/Source/Grug/AuArrow.cpp b/Source/Grug/AuArrow.cpp index c5763e85..61b234cd 100644 --- a/Source/Grug/AuArrow.cpp +++ b/Source/Grug/AuArrow.cpp @@ -17,15 +17,15 @@ namespace Aurora::Grug static AuThreadPrimitives::SpinLock gSpinLock; static bool gDisableGrugMessages {}; - void SignalSafeSleepLockYield(AuThreadPrimitives::SpinLock &lock) + void SignalSafeSleepLockYield(AuThreading::IWaitable *pLock) { #if defined(AURORA_IS_POSIX_DERIVED) - while (!lock.TryLock()) + while (!pLock->TryLock()) { sched_yield(); } #else - lock.Lock(); + pLock->Lock(); #endif } @@ -39,10 +39,14 @@ namespace Aurora::Grug pArrow->pCallback = pCallback; pArrow->pCallbackRunaway = pCallbackRunaway; - SignalSafeSleepLockYield(pArrow->spinSemaphore); + #if defined(ARROW_NO_MUTEX) + SignalSafeSleepLockYield(&pArrow->spinSemaphore); + #else + SignalSafeSleepLockYield(pArrow->spinSemaphore2.AsPointer()); + #endif { - SignalSafeSleepLockYield(gSpinLock); + SignalSafeSleepLockYield(&gSpinLock); while (!AuTryInsert(gReservedArrows, pArrow)) { @@ -65,13 +69,22 @@ namespace Aurora::Grug return; } + #if defined(ARROW_NO_MUTEX) AU_LOCK_GUARD(arrow->spinSemaphore); + #else + AU_LOCK_GUARD(arrow->spinSemaphore2); + #endif } void ArrowThreadAsyncSafe(Arrow *pArrow) { - SignalSafeSleepLockYield(pArrow->spinSemaphore); + #if defined(ARROW_NO_MUTEX) + SignalSafeSleepLockYield(&pArrow->spinSemaphore); pArrow->spinSemaphore.Unlock(); + #else + SignalSafeSleepLockYield(pArrow->spinSemaphore2.AsPointer()); + pArrow->spinSemaphore2->Unlock(); + #endif } void DequeueOneArrow() @@ -100,6 +113,7 @@ namespace Aurora::Grug auto lastCallback = last->pCallbackRunaway; last->spinSemaphore.Unlock(); + last->spinSemaphore2->Unlock(); gReservedArrows.pop_back(); diff --git a/Source/Grug/AuArrow.hpp b/Source/Grug/AuArrow.hpp index ffd82de4..6caddb3c 100644 --- a/Source/Grug/AuArrow.hpp +++ b/Source/Grug/AuArrow.hpp @@ -7,6 +7,10 @@ ***/ #pragma once +#if defined(AURORA_IS_POSIX_DERIVED) +#define ARROW_NO_MUTEX +#endif + namespace Aurora::Grug { struct Arrow; @@ -15,6 +19,9 @@ namespace Aurora::Grug struct Arrow { AuThreadPrimitives::SpinLock spinSemaphore; + #if !defined(ARROW_NO_MUTEX) + AuThreadPrimitives::Mutex spinSemaphore2; + #endif bool bPermitRunAhead; GrugThread thread; GrugReport_f pCallback;