[+] AuDebug::ErrorStack / AuErrorStack
[+] Begin stubbing out memory crunch apis [*] Fixed MT consoletty missed flushes
This commit is contained in:
parent
72dc0d715e
commit
89d341b4fc
@ -81,8 +81,30 @@ namespace Aurora::Debug
|
||||
AUKN_SYM AuResult<AuString> DemangleName(const AuString &pName);
|
||||
|
||||
AUKN_SYM void DebugBreak();
|
||||
|
||||
AUKN_SYM void AddMemoryCrunch();
|
||||
AUKN_SYM void DecMemoryCrunch();
|
||||
}
|
||||
|
||||
#include "SysPanic.hpp"
|
||||
#include "SysAssertions.hpp"
|
||||
#include "SysErrors.hpp"
|
||||
#include "SysErrors.hpp"
|
||||
#include "ErrorStack.hpp"
|
||||
|
||||
struct AuDbgStringSharedException : AuStringException
|
||||
{
|
||||
inline AuDbgStringSharedException(AuSPtr<AuString> pStr) noexcept :
|
||||
AuStringException(pStr->c_str()),
|
||||
pStr(pStr)
|
||||
{
|
||||
}
|
||||
|
||||
AuSPtr<AuString> pStr;
|
||||
};
|
||||
|
||||
#if defined(AU_THROW_STRING)
|
||||
#undef AU_THROW_STRING
|
||||
#endif
|
||||
|
||||
#define AU_THROW_STRING(var) do { Aurora::Debug::AddMemoryCrunch(); auto pStr = AuMakeSharedPanic<AuString>(var); Aurora::Debug::DecMemoryCrunch(); throw AuDbgStringSharedException(pStr); } while (0)
|
||||
#define AU_THROW_FORMATTED(var, ...) do { Aurora::Debug::AddMemoryCrunch(); auto pStr = AuMakeSharedPanic<AuString>(fmt::format(var, ##__VA_ARGS__)); Aurora::Debug::DecMemoryCrunch(); throw AuDbgStringSharedException(pStr); } while (0)
|
86
Include/Aurora/Debug/ErrorStack.hpp
Normal file
86
Include/Aurora/Debug/ErrorStack.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: ErrorStack.hpp
|
||||
Date: 2022-11-29
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Debug
|
||||
{
|
||||
struct ErrorStack;
|
||||
|
||||
AUKN_SYM void PushStack(ErrorStack *pStack);
|
||||
AUKN_SYM void PopStack(ErrorStack *pStack);
|
||||
|
||||
struct ErrorStackAccessor;
|
||||
|
||||
struct ThreadMessage
|
||||
{
|
||||
AuSPtr<ThreadMessage> pNextThreadMesage;
|
||||
|
||||
AuSPtr<AuString> pStringMessage;
|
||||
AuOptional<EFailureCategory> eFailureCategory;
|
||||
AuOptional<StackTrace> optStackTrace;
|
||||
AuOptional<AuUInt> optOsErrorCode;
|
||||
|
||||
AUKN_SYM AuString ToString();
|
||||
};
|
||||
|
||||
struct ErrorStack
|
||||
{
|
||||
inline ErrorStack()
|
||||
{
|
||||
PushStack(this);
|
||||
}
|
||||
|
||||
inline ~ErrorStack()
|
||||
{
|
||||
PopStack(this);
|
||||
}
|
||||
|
||||
inline bool HasCaptured()
|
||||
{
|
||||
CheckErrors();
|
||||
return bool(this->pHead);
|
||||
}
|
||||
|
||||
inline bool HasMultipleOccurred()
|
||||
{
|
||||
return this->HasCaptured() && bool(this->pHead->pNextThreadMesage);
|
||||
}
|
||||
|
||||
inline StackTrace *ToStackTrace()
|
||||
{
|
||||
if (!this->HasCaptured())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!this->pHead->optStackTrace)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return &this->pHead->optStackTrace.value();
|
||||
}
|
||||
|
||||
inline AuOptional<AuString> ToString()
|
||||
{
|
||||
return this->HasCaptured() ? this->pHead->ToString() : AuString {};
|
||||
}
|
||||
|
||||
inline AuSPtr<ThreadMessage> FirstMessage()
|
||||
{
|
||||
return this->pHead;
|
||||
}
|
||||
|
||||
protected:
|
||||
AuSPtr<ThreadMessage> pHead;
|
||||
ErrorStack *pNext {};
|
||||
friend ErrorStackAccessor;
|
||||
};
|
||||
}
|
||||
|
||||
using AuErrorStack = Aurora::Debug::ErrorStack;
|
@ -113,8 +113,8 @@ namespace Aurora::Debug
|
||||
|
||||
#define SysCheckReturn(x, ...) if (!(static_cast<bool>(x))) { Aurora::Debug::ErrorMakeNested(); return __VA_ARGS__; }
|
||||
|
||||
#define SysPushErrorError(error, ...) Aurora::Debug::SysPushError(Aurora::Debug::error, ## __VA_ARGS__)
|
||||
#define SysPushUserError(exp, ...) Aurora::Debug::SysPushError((Aurora::Debug::EFailureCategory)exp, ## __VA_ARGS__)
|
||||
#define SysPushErrorError(error, ...) do { Aurora::Debug::AddMemoryCrunch(); Aurora::Debug::SysPushError(Aurora::Debug::error, ## __VA_ARGS__) ;Aurora::Debug::DecMemoryCrunch(); } while (0)
|
||||
#define SysPushUserError(exp, ...) do { Aurora::Debug::AddMemoryCrunch(); Aurora::Debug::SysPushError((Aurora::Debug::EFailureCategory)exp, ## __VA_ARGS__) ;Aurora::Debug::DecMemoryCrunch(); } while (0)
|
||||
|
||||
// legacy
|
||||
#define SysPushErrorArg(...) SysPushErrorError(kFailureParam, ## __VA_ARGS__)
|
||||
|
@ -11,7 +11,15 @@
|
||||
template<typename ... T>
|
||||
static inline void AU_NORETURN SysPanic(T... args)
|
||||
{
|
||||
Aurora::Logging::WriteLinef(static_cast<AuUInt8>(Aurora::Logging::ELogLevel::eError), Aurora::Console::EAnsiColor::eBoldRed, "Fatal", AuForward<T>(args)...);
|
||||
Aurora::Debug::AddMemoryCrunch();
|
||||
try
|
||||
{
|
||||
Aurora::Logging::WriteLinef(static_cast<AuUInt8>(Aurora::Logging::ELogLevel::eError), Aurora::Console::EAnsiColor::eBoldRed, "Fatal", AuForward<T>(args)...);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
Aurora::Debug::Panic();
|
||||
}
|
||||
#endif
|
@ -154,6 +154,7 @@ namespace Aurora
|
||||
|
||||
AUKN_SYM void RuntimeShutdown()
|
||||
{
|
||||
RuntimeSysPump();
|
||||
gRuntimeHasStarted = false;
|
||||
Deinit();
|
||||
}
|
||||
|
@ -119,6 +119,14 @@ namespace Aurora::Console
|
||||
|
||||
void Exit()
|
||||
{
|
||||
try
|
||||
{
|
||||
ConsoleTTY::PumpForce();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
gDefaultSinks.clear();
|
||||
gDefaultLogger.reset();
|
||||
Logging::DeinitLoggers();
|
||||
|
@ -2069,6 +2069,11 @@ namespace Aurora::Console::ConsoleTTY
|
||||
}
|
||||
}
|
||||
|
||||
void PumpForce()
|
||||
{
|
||||
gTTYConsole.Pump();
|
||||
}
|
||||
|
||||
AUKN_SYM AuSPtr<ITTYConsole> GetTTYConsole()
|
||||
{
|
||||
return AuUnsafeRaiiToShared<ITTYConsole>(&gTTYConsole);
|
||||
@ -2094,6 +2099,11 @@ namespace Aurora::Console::ConsoleTTY
|
||||
|
||||
}
|
||||
|
||||
void PumpForce()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Exit()
|
||||
{
|
||||
|
||||
|
@ -268,4 +268,5 @@ namespace Aurora::Console::ConsoleTTY
|
||||
void OnEnter();
|
||||
void WriteTTYOut(const AuConsole::ConsoleMessage &msg);
|
||||
AUKN_SYM AuSPtr<ITTYConsole> GetTTYConsole();
|
||||
void PumpForce();
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
#include "Stack.Unix.hpp"
|
||||
#endif
|
||||
|
||||
#include "ErrorStack.hpp"
|
||||
|
||||
namespace Aurora::Debug
|
||||
{
|
||||
static thread_local AuUInt32 tlsLastBackTrace = 0xFFFFFFFF;
|
||||
@ -310,6 +312,21 @@ namespace Aurora::Debug
|
||||
|
||||
tlsCategory = category;
|
||||
|
||||
try
|
||||
{
|
||||
if (ShouldPushErrorStackInternal())
|
||||
{
|
||||
auto pMessage = AuMakeSharedThrow<ThreadMessage>();
|
||||
pMessage->pStringMessage = AuMakeSharedThrow<AuString>(msg);
|
||||
pMessage->eFailureCategory = category;
|
||||
PushErrorStackInternal(pMessage);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Cry about it to telemetry with other errors if available
|
||||
AuUInt32 rng = GetFenceId();
|
||||
Telemetry::BeginBlock();
|
||||
@ -333,7 +350,7 @@ namespace Aurora::Debug
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Print to console if internal
|
||||
#if defined(DEBUG) || defined(STAGING)
|
||||
PrintError();
|
||||
@ -345,6 +362,7 @@ namespace Aurora::Debug
|
||||
|
||||
AUKN_SYM AuString StackTraceEntry::Stringify() const
|
||||
{
|
||||
AddMemoryCrunch();
|
||||
const auto frame = *this;
|
||||
AuString backTraceBuffer;
|
||||
|
||||
@ -390,16 +408,19 @@ namespace Aurora::Debug
|
||||
backTraceBuffer += "\t\t[proprietary]\n";
|
||||
}
|
||||
|
||||
DecMemoryCrunch();
|
||||
return backTraceBuffer;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
DecMemoryCrunch();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
AUKN_SYM AuString StringifyStackTrace(const StackTrace &backtrace)
|
||||
{
|
||||
AddMemoryCrunch();
|
||||
AuString backTraceBuffer;
|
||||
|
||||
try
|
||||
@ -414,10 +435,12 @@ namespace Aurora::Debug
|
||||
backTraceBuffer += frame.Stringify();
|
||||
}
|
||||
|
||||
DecMemoryCrunch();
|
||||
return backTraceBuffer;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
DecMemoryCrunch();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@ -432,4 +455,14 @@ namespace Aurora::Debug
|
||||
InitNT();
|
||||
#endif
|
||||
}
|
||||
|
||||
AUKN_SYM void AddMemoryCrunch()
|
||||
{
|
||||
// TODO: ...
|
||||
}
|
||||
|
||||
AUKN_SYM void DecMemoryCrunch()
|
||||
{
|
||||
// TODO: ...
|
||||
}
|
||||
}
|
156
Source/Debug/ErrorStack.cpp
Normal file
156
Source/Debug/ErrorStack.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: ErrorStack.cpp
|
||||
Date: 2022-11-29
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "Debug.hpp"
|
||||
#include "ErrorStack.hpp"
|
||||
|
||||
namespace Aurora::Debug
|
||||
{
|
||||
struct ErrorStackAccessor
|
||||
{
|
||||
void SetNext(ErrorStack *pStack, ErrorStack *pNext)
|
||||
{
|
||||
pStack->pNext = pNext;
|
||||
}
|
||||
|
||||
ErrorStack *GetNext(ErrorStack *pStack)
|
||||
{
|
||||
return pStack->pNext;
|
||||
}
|
||||
|
||||
void SetHead(ErrorStack *pStack, AuSPtr<ThreadMessage> pHead)
|
||||
{
|
||||
pStack->pHead = pHead;
|
||||
}
|
||||
|
||||
AuSPtr<ThreadMessage> GetHead(ErrorStack *pStack)
|
||||
{
|
||||
return pStack->pHead;
|
||||
}
|
||||
};
|
||||
|
||||
AUKN_SYM AuString ThreadMessage::ToString()
|
||||
{
|
||||
if (this->pStringMessage)
|
||||
{
|
||||
return *this->pStringMessage;
|
||||
}
|
||||
|
||||
if (eFailureCategory)
|
||||
{
|
||||
return fmt::format("Debug::EFailureCategory = {}", (AuUInt)*eFailureCategory);
|
||||
}
|
||||
|
||||
if (optOsErrorCode)
|
||||
{
|
||||
return fmt::format("OS = {}", (AuUInt)*optOsErrorCode);
|
||||
}
|
||||
|
||||
return "Unknown error.";
|
||||
}
|
||||
|
||||
static thread_local ErrorStack *tlsErrorStackBase;
|
||||
|
||||
AUKN_SYM void PushStack(ErrorStack *pStack)
|
||||
{
|
||||
if (!tlsErrorStackBase)
|
||||
{
|
||||
tlsErrorStackBase = pStack;
|
||||
return;
|
||||
}
|
||||
|
||||
ErrorStackAccessor dumb;
|
||||
auto itr = tlsErrorStackBase;
|
||||
while (auto pNext = dumb.GetNext(itr))
|
||||
{
|
||||
itr = pNext;
|
||||
}
|
||||
|
||||
dumb.SetNext(itr, pStack);
|
||||
}
|
||||
|
||||
AUKN_SYM void PopStack(ErrorStack *pStack)
|
||||
{
|
||||
if (!tlsErrorStackBase)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ErrorStackAccessor dumb;
|
||||
auto itr = tlsErrorStackBase;
|
||||
|
||||
if (itr == pStack)
|
||||
{
|
||||
tlsErrorStackBase = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
while (auto pNext = dumb.GetNext(itr))
|
||||
{
|
||||
if (pNext == pStack)
|
||||
{
|
||||
dumb.SetNext(pStack, {});
|
||||
return;
|
||||
}
|
||||
|
||||
itr = pNext;
|
||||
}
|
||||
}
|
||||
|
||||
static void AddToInstance(ErrorStack *pStack, AuSPtr<ThreadMessage> pMessage)
|
||||
{
|
||||
ErrorStackAccessor dumb;
|
||||
if (!dumb.GetHead(pStack))
|
||||
{
|
||||
dumb.SetHead(pStack, pMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
AuSPtr<ThreadMessage> pMessage2 { dumb.GetHead(pStack) };
|
||||
|
||||
if (pMessage2 == pMessage)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (auto pNext = pMessage2->pNextThreadMesage)
|
||||
{
|
||||
if (pNext == pMessage)
|
||||
{
|
||||
return;
|
||||
}
|
||||
pMessage2 = pNext;
|
||||
}
|
||||
|
||||
pMessage2->pNextThreadMesage = pMessage;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// internal api:
|
||||
|
||||
bool ShouldPushErrorStackInternal()
|
||||
{
|
||||
return bool(tlsErrorStackBase);
|
||||
}
|
||||
|
||||
void PushErrorStackInternal(AuSPtr<ThreadMessage> pMessage)
|
||||
{
|
||||
ErrorStackAccessor dumb;
|
||||
auto itr = tlsErrorStackBase;
|
||||
|
||||
if (itr)
|
||||
{
|
||||
AddToInstance(itr, pMessage);
|
||||
while (auto pNext = dumb.GetNext(itr))
|
||||
{
|
||||
AddToInstance(itr, pMessage);
|
||||
itr = pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
14
Source/Debug/ErrorStack.hpp
Normal file
14
Source/Debug/ErrorStack.hpp
Normal file
@ -0,0 +1,14 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: ErrorStack.hpp
|
||||
Date: 2022-11-29
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Debug
|
||||
{
|
||||
void PushErrorStackInternal(AuSPtr<ThreadMessage> pMessage);
|
||||
bool ShouldPushErrorStackInternal();
|
||||
}
|
@ -18,6 +18,7 @@
|
||||
#include <Source/Telemetry/Telemetry.hpp>
|
||||
#include <Source/Grug/AuGrug.hpp>
|
||||
#include <Source/Exit/AuExit.hpp>
|
||||
#include "ErrorStack.hpp"
|
||||
|
||||
namespace Aurora::Debug
|
||||
{
|
||||
@ -135,6 +136,24 @@ namespace Aurora::Debug
|
||||
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
auto pStr = AuMakeSharedThrow<AuString>(message);
|
||||
// auto pTrace = AuMakeSharedThrow<StackTrace>(trace);
|
||||
|
||||
if (ShouldPushErrorStackInternal())
|
||||
{
|
||||
auto pMessage = AuMakeSharedThrow<ThreadMessage>();
|
||||
pMessage->optStackTrace = trace;
|
||||
pMessage->pStringMessage = pStr;
|
||||
PushErrorStackInternal(pMessage);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "Panic.hpp"
|
||||
//#include <intrin.h>
|
||||
#include <Source/Grug/AuGrug.hpp>
|
||||
#include <Source/Console/ConsoleTTY/ConsoleTTY.hpp>
|
||||
#include <Source/Console/Console.hpp>
|
||||
|
||||
namespace Aurora::Debug
|
||||
{
|
||||
@ -64,6 +66,15 @@ namespace Aurora::Debug
|
||||
goto failFast;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Console::ConsoleTTY::PumpForce();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Grug::GrugFlushFlushs();
|
||||
@ -76,6 +87,16 @@ namespace Aurora::Debug
|
||||
|
||||
failFast:
|
||||
|
||||
try
|
||||
{
|
||||
Console::Pump();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
static bool runPlatformFastFailOnce {};
|
||||
if (!AuExchange(runPlatformFastFailOnce, true))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user