[*] "Improve" win32 AuDebug
This commit is contained in:
parent
942373328c
commit
5aea27d56d
@ -258,14 +258,37 @@ namespace Aurora
|
||||
struct FIOConfig
|
||||
{
|
||||
/// You can bypass branding by assigning an empty string to 'defaultBrand'
|
||||
AuString defaultBrand = "Aurora";
|
||||
AuString defaultBrand = "Aurora SDK Sample";
|
||||
};
|
||||
|
||||
struct DebugConfig
|
||||
{
|
||||
/**
|
||||
* @brief Precache/initialize symbols for printable stack traces under binaries not intended for shipping to consumers
|
||||
*/
|
||||
bool nonshipPrecachesSymbols {true};
|
||||
|
||||
/**
|
||||
* @brief Activates the internal AddVectoredExceptionHandler handler. Might conflict with DRM and other debugging utilities
|
||||
*/
|
||||
bool enableWin32RootExceptionHandler {true};
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*/
|
||||
bool enableInjectedExceptionHandler {true};
|
||||
|
||||
/**
|
||||
* @brief Causes a SysPanic
|
||||
*/
|
||||
bool isMemoryErrorFatal {false};
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*/
|
||||
bool isExceptionThrowFatal {false};
|
||||
|
||||
bool printExceptionStackTracesOut {true};
|
||||
};
|
||||
|
||||
struct RuntimeStartInfo
|
||||
|
@ -237,14 +237,22 @@ extern "C" AUKN_SYM void __stdcall _ReportMSVCSEH(void *exception, const void *t
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
auto trace = AuDebug::GetStackTrace();
|
||||
AuDebug::ReportSEH(handle, exception, throwInfo, {}, trace,
|
||||
[&](const AuString &str)
|
||||
|
||||
if (gRuntimeConfig.debug.printExceptionStackTracesOut)
|
||||
{
|
||||
AuLogWarn("Local MSVC Exception: 0x{:x}, {}", exception, str.c_str());
|
||||
AuLogWarn("{}", StringifyStackTrace(trace));
|
||||
});
|
||||
AuDebug::ReportSEH(handle, exception, throwInfo, {}, trace,
|
||||
[&](const AuString &str)
|
||||
{
|
||||
AuLogWarn("Local MSVC Exception: 0x{:x}, {}", exception, str.c_str());
|
||||
AuLogWarn("{}", StringifyStackTrace(trace));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
AuDebug::ReportSEH(handle, exception, throwInfo, {}, trace,
|
||||
[&](const AuString &str) {});
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
@ -106,26 +106,53 @@ namespace Aurora::Debug
|
||||
return (info.Protect & (PAGE_READONLY | PAGE_READWRITE)) != 0;
|
||||
}
|
||||
|
||||
bool InPanic();
|
||||
|
||||
static LONG CALLBACK HandleVectorException(_EXCEPTION_POINTERS *ExceptionInfo)
|
||||
{
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == DBG_CONTROL_C)
|
||||
{
|
||||
Exit::PostLevel(AuThreads::GetThread(), Exit::ETriggerLevel::eSigTerminate);
|
||||
return Exit::gHasCanceled ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH;
|
||||
return AuExchange(Exit::gHasCanceled, false) ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// https://www.youtube.com/embed/w6P03sTzSqM?start=2&autoplay=1
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode < STATUS_GUARD_PAGE_VIOLATION)
|
||||
{
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
#if defined(AU_CFG_ID_SHIP)
|
||||
|
||||
// you what?
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
|
||||
{
|
||||
SysPanic("");
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// debugger go brrr
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
|
||||
{
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
auto minimal = gDebugLocked++;
|
||||
#endif
|
||||
|
||||
// debug builds can go do something stupid
|
||||
// QA builds, staging, rel in any form should just give up trying if we're under a panic
|
||||
#if !defined(AU_CFG_ID_DEBUG)
|
||||
if (InPanic())
|
||||
{
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
#endif
|
||||
|
||||
// something dumb like this mess w hat i had before.
|
||||
// gave up trying
|
||||
auto minimal = gDebugLocked++;
|
||||
if (minimal >= 5)
|
||||
{
|
||||
SysPanic("Nested Exception");
|
||||
@ -177,7 +204,6 @@ namespace Aurora::Debug
|
||||
StackTrace backtrace;
|
||||
ParseStack(ExceptionInfo->ContextRecord, backtrace);
|
||||
|
||||
|
||||
#if defined(_AU_USE_EXTENDED_FWD_FACING_DEBUGGING)
|
||||
bool isInternal = true;
|
||||
#else
|
||||
@ -191,26 +217,29 @@ namespace Aurora::Debug
|
||||
// Pre-submit callback -> its showtime
|
||||
if ((isCritical || isInternal) && (minimal == 0))
|
||||
{
|
||||
AuLogWarn("NT Exception: 0x{:x}, {}", ExceptionInfo->ExceptionRecord->ExceptionCode, str);
|
||||
AuLogWarn("{}", StringifyStackTrace(backtrace));
|
||||
if (gRuntimeConfig.debug.printExceptionStackTracesOut)
|
||||
{
|
||||
AuLogWarn("NT Exception: 0x{:x}, {}", ExceptionInfo->ExceptionRecord->ExceptionCode, str);
|
||||
AuLogWarn("{}", StringifyStackTrace(backtrace));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Grug::Arrow empty;
|
||||
Grug::HurlRaiseProblematicEvent(&empty);
|
||||
|
||||
if (isCritical)
|
||||
{
|
||||
Telemetry::Mayday();
|
||||
}
|
||||
|
||||
if (isCritical)
|
||||
if (isCritical || gRuntimeConfig.debug.isExceptionThrowFatal) // exception = literally anything
|
||||
{
|
||||
PlatformHandleFatal(true);
|
||||
}
|
||||
|
||||
Grug::Arrow empty;
|
||||
Grug::HurlRaiseProblematicEvent(&empty);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -314,15 +343,13 @@ namespace Aurora::Debug
|
||||
{
|
||||
AuString path;
|
||||
HANDLE hFile;
|
||||
std::wstring wpath;
|
||||
AuString utf8Path;
|
||||
MINIDUMP_EXCEPTION_INFORMATION info;
|
||||
|
||||
auto ok = AuIOFS::GetProfileDomain(path);
|
||||
auto ok = AuIOFS::GetProfileDomain(path); // < could throw inside
|
||||
if (!ok)
|
||||
{
|
||||
AuLogWarn("Couldn't find minidump directory");
|
||||
goto miniMiniDumpOut;
|
||||
path = ".\\";
|
||||
}
|
||||
|
||||
info.ClientPointers = true;
|
||||
@ -336,22 +363,22 @@ namespace Aurora::Debug
|
||||
MiniDumpWithThreadInfo;
|
||||
|
||||
|
||||
while (wpath.empty())
|
||||
{
|
||||
try
|
||||
{
|
||||
utf8Path = path + "Crashes/" + GetDumpName();
|
||||
wpath = Locale::ConvertFromUTF8(utf8Path);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
static std::wstring pathStorage(8192, L' ');
|
||||
|
||||
}
|
||||
}
|
||||
int index {};
|
||||
|
||||
AuIOFS::CreateDirectories(utf8Path, true);
|
||||
index += MultiByteToWideChar(CP_UTF8, 0, path.c_str(), path.length(), pathStorage.data() + index, pathStorage.size() - index);
|
||||
static const std::string crashesSlash = "Crashes\\";
|
||||
index += MultiByteToWideChar(CP_UTF8, 0, crashesSlash.c_str(), crashesSlash.length(), pathStorage.data() + index, pathStorage.size() - index);
|
||||
|
||||
hFile = CreateFileW(wpath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
auto dumpName = GetDumpName();;
|
||||
index += MultiByteToWideChar(CP_UTF8, 0, dumpName.c_str(), dumpName.length(), pathStorage.data() + index, pathStorage.size() - index);
|
||||
|
||||
pathStorage.resize(index);
|
||||
|
||||
AuIOFS::CreateDirectories(utf8Path, true); // potentially unsafe / could throw inside
|
||||
|
||||
hFile = CreateFileW(pathStorage.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
AuLogWarn("[1] Couldn't open minidump file. Has a debugger locked the .dmp file?");
|
||||
@ -370,7 +397,7 @@ namespace Aurora::Debug
|
||||
miniMiniDumpOut:
|
||||
Telemetry::NewBlackBoxEntryMinidump report {};
|
||||
report.includesRx = false;
|
||||
report.resource.path = path;
|
||||
report.resource.path = dumpName; // <COPY
|
||||
report.resource.type = Telemetry::ENewBlackBoxResourceType::eLocal;
|
||||
Telemetry::ReportDyingBreath(report);
|
||||
|
||||
@ -382,7 +409,7 @@ namespace Aurora::Debug
|
||||
|
||||
static void CacheInternalBuildSymbols()
|
||||
{
|
||||
#if defined(DEBUG) || defined(STAGING)
|
||||
#if defined(AU_CFG_ID_INTERNAL) || defined(AU_CFG_ID_DEBUG)
|
||||
SymInitialize(GetCurrentProcess(), NULL, TRUE);
|
||||
#endif
|
||||
}
|
||||
@ -418,6 +445,9 @@ namespace Aurora::Debug
|
||||
DisableWindowsErrorReporting();
|
||||
|
||||
// ..
|
||||
AddVectoredExceptionHandler(1, HandleVectorException);
|
||||
if (gRuntimeConfig.debug.enableWin32RootExceptionHandler)
|
||||
{
|
||||
AddVectoredExceptionHandler(1, HandleVectorException);
|
||||
}
|
||||
}
|
||||
}
|
@ -14,12 +14,13 @@
|
||||
namespace Aurora::Debug
|
||||
{
|
||||
void PlatformHandleFatal();
|
||||
static bool gHandlingFatal = false;
|
||||
|
||||
AUKN_SYM void DebugBreak()
|
||||
{
|
||||
#if defined(DEBUG) || defined(STAGING)
|
||||
#if defined(AU_CFG_ID_INTERNAL) || defined(AU_CFG_ID_DEBUG)
|
||||
#if defined(AURORA_PLATFORM_WIN32)
|
||||
#if defined(STAGING)
|
||||
#if defined(AU_CFG_ID_INTERNAL)
|
||||
if (IsDebuggerPresent())
|
||||
#endif
|
||||
{
|
||||
@ -38,35 +39,27 @@ namespace Aurora::Debug
|
||||
#endif
|
||||
}
|
||||
|
||||
bool InPanic()
|
||||
{
|
||||
return gHandlingFatal;
|
||||
}
|
||||
|
||||
AUKN_SYM void Panic()
|
||||
{
|
||||
//
|
||||
static bool handlingFatal = false;
|
||||
if (AuExchange(handlingFatal, true))
|
||||
if (gHandlingFatal)
|
||||
{
|
||||
goto failFast;
|
||||
}
|
||||
|
||||
#if defined(AU_CFG_ID_DEBUG)
|
||||
DebugBreak();
|
||||
#endif
|
||||
|
||||
try
|
||||
if (AuExchange(gHandlingFatal, true))
|
||||
{
|
||||
CheckErrors();
|
||||
goto failFast;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Grug::GrugFlushFlushs();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
@ -78,20 +71,21 @@ namespace Aurora::Debug
|
||||
|
||||
}
|
||||
|
||||
static bool panicSingleshot = false;
|
||||
if (AuExchange(panicSingleshot, true))
|
||||
failFast:
|
||||
|
||||
static bool runPlatformFastFailOnce {};
|
||||
if (!AuExchange(runPlatformFastFailOnce, true))
|
||||
{
|
||||
try
|
||||
{
|
||||
Telemetry::Mayday();
|
||||
Debug::PlatformHandleFatal(true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
failFast:
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
__fastfail('FCKD');
|
||||
#else
|
||||
|
@ -7,3 +7,7 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Debug
|
||||
{
|
||||
bool InPanic();
|
||||
}
|
Loading…
Reference in New Issue
Block a user