[+] ErrorStack::HasOOMCondition()

This commit is contained in:
Reece Wilson 2024-02-14 00:32:30 +00:00
parent 8b64a97514
commit 11e18d462a
4 changed files with 102 additions and 10 deletions

View File

@ -23,7 +23,7 @@ namespace Aurora::Debug
AuOptional<AuUInt> optOsErrorCode; AuOptional<AuUInt> optOsErrorCode;
AuUInt16 uDebugBuildSourceLineHint {}; AuUInt16 uDebugBuildSourceLineHint {};
AUKN_SYM AuString ToString(); AUKN_SYM const AuString &ToString();
}; };
struct ErrorStack struct ErrorStack
@ -42,7 +42,7 @@ namespace Aurora::Debug
return this->HasCaptured() && bool(this->pHead->pNextThreadMesage); return this->HasCaptured() && bool(this->pHead->pNextThreadMesage);
} }
inline StackTrace *ToStackTrace() inline AuOptional<const StackTrace &>ToStackTrace()
{ {
if (!this->HasCaptured()) if (!this->HasCaptured())
{ {
@ -54,23 +54,43 @@ namespace Aurora::Debug
return {}; return {};
} }
return &this->pHead->optStackTrace.value(); return this->pHead->optStackTrace.value();
} }
inline AuOptional<AuString> ToString() inline AuOptional<const AuString&> ToString()
{ {
return this->HasCaptured() ? this->pHead->ToString() : AuString {}; static const AuString kOutOfMemoryString = "Aurora: Out of Memory";
if (this->HasCaptured())
{
return this->pHead->ToString();
}
else if (this->HasOOMCondition())
{
return kOutOfMemoryString;
}
else
{
return {};
}
} }
inline AuSPtr<ThreadMessage> FirstMessage() inline AuSPtr<ThreadMessage> FirstMessage()
{ {
return this->pHead; return this->pHead;
} }
inline bool HasOOMCondition()
{
return this->bOutOfMemory;
}
protected: protected:
friend ErrorStackAccessor;
AuSPtr<ThreadMessage> pHead; AuSPtr<ThreadMessage> pHead;
ErrorStack *pNext {}; ErrorStack *pNext {};
friend ErrorStackAccessor; bool bOutOfMemory {};
}; };
} }

View File

@ -17,6 +17,9 @@
namespace Aurora::Debug namespace Aurora::Debug
{ {
static thread_local AuString tlsLastMessageError;
static AuString strFailureCategoryCache[128];
struct ErrorStackAccessor struct ErrorStackAccessor
{ {
void SetNext(ErrorStack *pStack, ErrorStack *pNext) void SetNext(ErrorStack *pStack, ErrorStack *pNext)
@ -38,9 +41,14 @@ namespace Aurora::Debug
{ {
return pStack->pHead; return pStack->pHead;
} }
void SetOOM(ErrorStack *pStack)
{
pStack->bOutOfMemory = true;
}
}; };
AUKN_SYM AuString ThreadMessage::ToString() AUKN_SYM const AuString &ThreadMessage::ToString()
{ {
if (this->pStringMessage) if (this->pStringMessage)
{ {
@ -49,12 +57,30 @@ namespace Aurora::Debug
if (eFailureCategory) if (eFailureCategory)
{ {
return fmt::format("Debug::EFailureCategory = {}", (AuUInt)*eFailureCategory); auto uIndex = (AuUInt)*eFailureCategory;
if (AuArraySize(strFailureCategoryCache) <= uIndex)
{
return tlsLastMessageError = fmt::format("Debug::EFailureCategory = {}", (AuUInt)*eFailureCategory);
}
else
{
auto &stringBuffer = strFailureCategoryCache[uIndex];
if (stringBuffer.size())
{
return stringBuffer;
}
else
{
return stringBuffer = fmt::format("Debug::EFailureCategory = {}", (AuUInt)*eFailureCategory);
}
}
} }
if (optOsErrorCode) if (optOsErrorCode)
{ {
return fmt::format("OS = {}", (AuUInt)*optOsErrorCode); return tlsLastMessageError = fmt::format("OS = {}", (AuUInt)*optOsErrorCode);
} }
return "Unknown error."; return "Unknown error.";
@ -163,4 +189,20 @@ namespace Aurora::Debug
} }
} }
} }
void OnOutOfMemory()
{
ErrorStackAccessor dumb;
auto itr = tlsErrorStackBase;
if (itr)
{
dumb.SetOOM(itr);
while (auto pNext = dumb.GetNext(itr))
{
dumb.SetOOM(itr);
itr = pNext;
}
}
}
} }

View File

@ -9,6 +9,7 @@
namespace Aurora::Debug namespace Aurora::Debug
{ {
void OnOutOfMemory();
void PushErrorStackInternal(AuSPtr<ThreadMessage> pMessage); void PushErrorStackInternal(AuSPtr<ThreadMessage> pMessage);
bool ShouldPushErrorStackInternal(); bool ShouldPushErrorStackInternal();
} }

View File

@ -15,6 +15,7 @@
#endif #endif
#include <Source/Debug/MemoryCrunch.hpp> #include <Source/Debug/MemoryCrunch.hpp>
#include <Source/Debug/ErrorStack.hpp>
namespace Aurora::Memory namespace Aurora::Memory
{ {
@ -66,11 +67,23 @@ namespace Aurora::Memory
} }
} }
static void OnOOM(AuUInt uLength)
{
tlsLastOutOfMemory = AuTime::CurrentClockNS();
AuDebug::OnOutOfMemory();
if (auto pLowNotification = tlsMemoryLowNotification)
{
pLowNotification(uLength, 4);
}
}
#define CHECK_WRAP_RETURN(exp, exp2, string) \ #define CHECK_WRAP_RETURN(exp, exp2, string) \
auto pRet = exp; \ auto pRet = exp; \
if (!pRet) \ if (!pRet) \
{ \ { \
tlsLastOutOfMemory = AuTime::CurrentClockNS(); \ OnOOM(length); \
\ \
bool bCrunchFlag {}; \ bool bCrunchFlag {}; \
if (((bCrunchFlag = AuDebug::IsTlsMemoryCrunchActive()) || \ if (((bCrunchFlag = AuDebug::IsTlsMemoryCrunchActive()) || \
@ -165,6 +178,10 @@ namespace Aurora::Memory
gLeakFinderAlloc(pRet, uNewSize); gLeakFinderAlloc(pRet, uNewSize);
} }
} }
else if (buffer && length)
{
OnOOM(length);
}
} }
if (!pRet) if (!pRet)
@ -210,6 +227,10 @@ namespace Aurora::Memory
gLeakFinderAlloc(pRet, uNewSize); gLeakFinderAlloc(pRet, uNewSize);
} }
} }
else if (buffer && length)
{
OnOOM(length);
}
} }
if (!pRet) if (!pRet)
@ -255,6 +276,10 @@ namespace Aurora::Memory
gLeakFinderAlloc(pRet, uNewSize); gLeakFinderAlloc(pRet, uNewSize);
} }
} }
else if (buffer && length)
{
OnOOM(length);
}
} }
if (!pRet) if (!pRet)
@ -300,6 +325,10 @@ namespace Aurora::Memory
gLeakFinderAlloc(pRet, uNewSize); gLeakFinderAlloc(pRet, uNewSize);
} }
} }
else if (buffer && length)
{
OnOOM(length);
}
} }
if (!pRet) if (!pRet)