[*] Linux and Posix targets now respect gRuntimeConfig.debug.bIsExceptionThrowFatal

This commit is contained in:
Reece Wilson 2024-03-10 00:09:12 +00:00
parent 3c4cece69d
commit 3c6d5a020b
3 changed files with 145 additions and 38 deletions

View File

@ -35,9 +35,9 @@ namespace Aurora::CmdLine
static AuList<AuString> GetProcFSCmdString() static AuList<AuString> GetProcFSCmdString()
{ {
AuList<AuString> args; AuList<AuString> args;
AuByteBuffer ret; AuString ret;
AuIOFS::ReadFile("/proc/self/cmdline", ret); AuIOFS::ReadString("/proc/self/cmdline", ret);
AuUInt idx {}; AuUInt idx {};
for (int i = 0; i < ret.size(); i++) for (int i = 0; i < ret.size(); i++)

View File

@ -31,6 +31,10 @@
#define DEBUG_ABI_IS_IT_AND_SYSV_LIKE #define DEBUG_ABI_IS_IT_AND_SYSV_LIKE
#endif #endif
#if defined(AURORA_PLATFORM_LINUX)
#include <libunwind.h>
#endif
namespace Aurora::Debug namespace Aurora::Debug
{ {
static const AuUInt8 kCriticalAlwaysCoreDumpSignals[] { static const AuUInt8 kCriticalAlwaysCoreDumpSignals[] {
@ -89,6 +93,7 @@ namespace Aurora::Debug
void *context {}; void *context {};
AuUInt32 uPosixThread {}; AuUInt32 uPosixThread {};
AuUInt thread; AuUInt thread;
AuString signalStr;
}; };
static void SendLogMessage(Grug::Arrow *pArrow) static void SendLogMessage(Grug::Arrow *pArrow)
@ -153,6 +158,61 @@ namespace Aurora::Debug
PosixTerminate(); PosixTerminate();
} }
static void SendCoreDumpOfException(Grug::Arrow *pArrow)
{
auto pArrowEx = AuStaticCast<SigArrow>(pArrow);
{
StackTrace trace;
if (pArrowEx->context)
{
trace = DumpContext(pArrowEx->context);
}
if (gRuntimeConfig.debug.bPrintExceptionStackTracesOut)
{
AuLogWarn("Fatal Exception: 0x{:x}, {}", pArrowEx->thread, pArrowEx->signalStr);
AuLogWarn("{}", StringifyStackTrace(trace));
}
{
Telemetry::NewBlockboxEntry entry;
entry.type = Telemetry::ENewBlackBoxEntry::eStackWarning;
entry.stack.fenceId = ReportStackTrace(trace, AuToString(pArrowEx->signal));
entry.stack.backtrace = trace;
Telemetry::Report(entry);
}
}
{
Exit::PostLevel((AuThreads::IAuroraThread *)pArrowEx->thread, Exit::ETriggerLevel::eFatalException);
}
{
AuString path;
SaveMinidump(pArrowEx->context, nullptr, pArrowEx->signal, pArrowEx->uPosixThread, path);
if (path.size())
{
Telemetry::NewBlackBoxEntryMinidump report {};
report.includesRx = false;
report.resource.path = path;
report.resource.type = Telemetry::ENewBlackBoxResourceType::eLocal;
Telemetry::ReportDyingBreath(report);
}
}
{
Grug::GrugFlushWrites();
Grug::GrugFlushFlushs();
Console::Pump();
}
PosixTerminate();
}
static void PosixCrashTrap(int signal, siginfo_t *si, void *context) static void PosixCrashTrap(int signal, siginfo_t *si, void *context)
{ {
void (*pSendExitSignal_f)(Grug::Arrow *); void (*pSendExitSignal_f)(Grug::Arrow *);
@ -186,6 +246,21 @@ namespace Aurora::Debug
} }
} }
static void PosixSendExceptionCrash(const AuString &str, void *context)
{
SigArrow arrow;
arrow.signalStr = str;
arrow.thread = AuThreads::GetThreadId();
arrow.context = context;
arrow.uPosixThread = getpid();
Grug::HurlArrow(&arrow, SendCoreDumpOfException, {});
Grug::ArrowWait(&arrow);
PosixTerminate();
}
void PlatformHandleFatal(bool bFatal, bool bNoExit) void PlatformHandleFatal(bool bFatal, bool bNoExit)
{ {
PlatformHandleFatalEx(bFatal, bNoExit, nullptr, getpid()); PlatformHandleFatalEx(bFatal, bNoExit, nullptr, getpid());
@ -335,6 +410,67 @@ namespace Aurora::Debug
} }
} }
static void PosixHandleExceptionThrow(void *pException, std::type_info *pInfo, bool bLinuxException)
{
AU_DEBUG_MEMCRUNCH;
#if defined(AURORA_PLATFORM_LINUX)
::unw_context_t uc;
::unw_getcontext(&uc);
void *pContext = &uc;
auto trace = DumpContext(uc);
#else
auto trace = GetStackTrace();
void *pContext = nullptr;
#endif
AuString reportFatal;
if (gRuntimeConfig.debug.bPrintExceptionStackTracesOut)
{
ReportException(pException, pInfo, trace, [&](const AuString &str)
{
if (bLinuxException)
{
AuLogWarn("Local Linux Exception: 0x{:x}, {}", AuUInt(pException), str.c_str());
}
else
{
AuLogWarn("Local Clang Exception: 0x{:x}, {}", AuUInt(pException), str.c_str());
}
AuLogWarn("{}", StringifyStackTrace(trace));
if (gRuntimeConfig.debug.bIsExceptionThrowFatal)
{
reportFatal = str;
}
});
}
else
{
if (gRuntimeConfig.debug.bIsExceptionThrowFatal)
{
ReportException(pException, pInfo, trace, [&](const AuString &str)
{
reportFatal = str;
});
}
else
{
ReportException(pException, pInfo, trace);
}
}
if (gRuntimeConfig.debug.bIsExceptionThrowFatal)
{
PosixSendExceptionCrash(reportFatal, pContext);
}
else
{
AuExit::PostLevel(AuThreads::GetThread(), AuExit::ETriggerLevel::eProblematicEvent);
}
}
static AU_NORETURN void __au_cxa_throw(void *pException, std::type_info *pInfo, void (*fDtor)(void *pThis)) static AU_NORETURN void __au_cxa_throw(void *pException, std::type_info *pInfo, void (*fDtor)(void *pThis))
{ {
if (Grug::IsGrug()) if (Grug::IsGrug())
@ -344,24 +480,7 @@ namespace Aurora::Debug
} }
{ {
AU_DEBUG_MEMCRUNCH; PosixHandleExceptionThrow(pException, pInfo, false);
auto trace = GetStackTrace();
if (gRuntimeConfig.debug.bPrintExceptionStackTracesOut)
{
ReportException(pException, pInfo, trace, [&](const AuString &str)
{
AuLogWarn("Local Clang Exception: 0x{:x}, {}", AuUInt(pException), str.c_str());
AuLogWarn("{}", StringifyStackTrace(trace));
});
}
else
{
ReportException(pException, pInfo, trace);
}
AuExit::PostLevel(AuThreads::GetThread(), Aurora::Exit::ETriggerLevel::eProblematicEvent);
} }
{ {
@ -380,24 +499,7 @@ namespace Aurora::Debug
} }
{ {
AU_DEBUG_MEMCRUNCH; PosixHandleExceptionThrow(pException, pInfo, true);
auto trace = GetStackTrace();
if (gRuntimeConfig.debug.bPrintExceptionStackTracesOut)
{
ReportException(pException, pInfo, trace, [&](const AuString &str)
{
AuLogWarn("Local Linux Exception: 0x{:x}, {}", AuUInt(pException), str.c_str());
AuLogWarn("{}", StringifyStackTrace(trace));
});
}
else
{
ReportException(pException, pInfo, trace);
}
AuExit::PostLevel(AuThreads::GetThread(), Aurora::Exit::ETriggerLevel::eProblematicEvent);
} }
{ {

View File

@ -86,6 +86,11 @@ namespace Aurora::Debug
return DumpContext((unw_context_t *)&uc); return DumpContext((unw_context_t *)&uc);
} }
StackTrace DumpContext(ucontext_t &uc)
{
return DumpContextPlatform(uc);
}
StackTrace DumpContext(void *pContext) StackTrace DumpContext(void *pContext)
{ {
return DumpContext((unw_context_t *)pContext); return DumpContext((unw_context_t *)pContext);