[Exception] Added better exception handling so that when the users are morons it explains exactly what happened to them.... cause they're morons
This commit is contained in:
parent
16a2d93801
commit
23ff36d590
@ -20,6 +20,7 @@ namespace Components
|
||||
|
||||
Loader::Register(new Flags());
|
||||
Loader::Register(new Singleton());
|
||||
Loader::Register(new Exception()); // install our exception handler as early as posssible to get better debug dumps from startup crashes
|
||||
|
||||
Loader::Register(new Auth());
|
||||
Loader::Register(new Bans());
|
||||
@ -58,7 +59,6 @@ namespace Components
|
||||
Loader::Register(new Changelog());
|
||||
Loader::Register(new Dedicated());
|
||||
Loader::Register(new Discovery());
|
||||
Loader::Register(new Exception());
|
||||
Loader::Register(new FastFiles());
|
||||
Loader::Register(new FrameTime());
|
||||
Loader::Register(new Gametypes());
|
||||
|
@ -24,27 +24,52 @@ namespace Components
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
const char* errorStr;
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW)
|
||||
{
|
||||
errorStr = "Termination because of a stack overflow.";
|
||||
}
|
||||
else
|
||||
{
|
||||
errorStr = Utils::String::VA("Fatal error (0x%08X) at 0x%08X.", ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);
|
||||
}
|
||||
|
||||
bool doFullDump = Flags::HasFlag("bigdumps") || Flags::HasFlag("reallybigdumps");
|
||||
if (!doFullDump)
|
||||
{
|
||||
if (MessageBoxA(NULL,
|
||||
Utils::String::VA("IW4x has encountered an exception and needs to close.\n"
|
||||
"%s\n" // errorStr
|
||||
"Would you like to create a full crash dump for the developers? (this can be almost 100mb)", errorStr),
|
||||
"IW4x Error!", MB_YESNO | MB_ICONERROR) == IDYES)
|
||||
{
|
||||
doFullDump = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (doFullDump)
|
||||
{
|
||||
Exception::SetMiniDumpType(true, false);
|
||||
}
|
||||
|
||||
auto minidump = MinidumpUpload::CreateQueuedMinidump(ExceptionInfo, Exception::MiniDumpType);
|
||||
if (!minidump)
|
||||
{
|
||||
MessageBoxA(NULL, "Minidump Error",
|
||||
Utils::String::VA("There was an error creating the minidump (%s)! Hit OK to close the program.", Utils::GetLastWindowsError()), MB_OK | MB_ICONERROR);
|
||||
OutputDebugStringA("Failed to create new minidump!");
|
||||
Utils::OutputDebugLastError();
|
||||
TerminateProcess(GetCurrentProcess(), ExceptionInfo->ExceptionRecord->ExceptionCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete minidump;
|
||||
}
|
||||
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW)
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionFlags == EXCEPTION_NONCONTINUABLE)
|
||||
{
|
||||
Logger::Error("Termination because of a stack overflow.\n");
|
||||
TerminateProcess(GetCurrentProcess(), ExceptionInfo->ExceptionRecord->ExceptionCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::Error("Fatal error (0x%08X) at 0x%08X.", ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);
|
||||
}
|
||||
|
||||
//TerminateProcess(GetCurrentProcess(), ExceptionInfo->ExceptionRecord->ExceptionCode);
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
@ -62,33 +87,29 @@ namespace Components
|
||||
return SetUnhandledExceptionFilter(&Exception::ExceptionFilter);
|
||||
}
|
||||
|
||||
void Exception::SetMiniDumpType()
|
||||
void Exception::SetMiniDumpType(bool codeseg, bool dataseg)
|
||||
{
|
||||
Exception::MiniDumpType = MiniDumpIgnoreInaccessibleMemory;
|
||||
Exception::MiniDumpType |= MiniDumpWithUnloadedModules;
|
||||
Exception::MiniDumpType |= MiniDumpWithThreadInfo;
|
||||
Exception::MiniDumpType |= MiniDumpWithFullMemoryInfo;
|
||||
Exception::MiniDumpType |= MiniDumpWithHandleData;
|
||||
Exception::MiniDumpType |= MiniDumpWithTokenInformation;
|
||||
Exception::MiniDumpType |= MiniDumpScanMemory;
|
||||
Exception::MiniDumpType |= MiniDumpWithProcessThreadData;
|
||||
Exception::MiniDumpType |= MiniDumpWithFullAuxiliaryState;
|
||||
Exception::MiniDumpType |= MiniDumpWithFullMemoryInfo;
|
||||
Exception::MiniDumpType |= MiniDumpWithThreadInfo;
|
||||
//Exception::MiniDumpType |= MiniDumpWithModuleHeaders;
|
||||
|
||||
if (Flags::HasFlag("bigminidumps"))
|
||||
if (codeseg)
|
||||
{
|
||||
Exception::MiniDumpType |= MiniDumpWithModuleHeaders;
|
||||
Exception::MiniDumpType |= MiniDumpWithCodeSegs;
|
||||
}
|
||||
else if (Flags::HasFlag("reallybigminidumps"))
|
||||
if (dataseg)
|
||||
{
|
||||
Exception::MiniDumpType |= MiniDumpWithModuleHeaders;
|
||||
Exception::MiniDumpType |= MiniDumpWithCodeSegs;
|
||||
Exception::MiniDumpType |= MiniDumpWithDataSegs;
|
||||
}
|
||||
}
|
||||
|
||||
Exception::Exception()
|
||||
{
|
||||
Exception::SetMiniDumpType();
|
||||
Exception::SetMiniDumpType(Flags::HasFlag("bigminidumps"), Flags::HasFlag("reallybigminidumps"));
|
||||
|
||||
#ifdef DEBUG
|
||||
// Display DEBUG branding, so we know we're on a debug build
|
||||
|
@ -14,7 +14,7 @@ namespace Components
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER Hook();
|
||||
|
||||
static int MiniDumpType;
|
||||
static void SetMiniDumpType();
|
||||
static void SetMiniDumpType(bool codeseg, bool dataseg);
|
||||
|
||||
private:
|
||||
static LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS ExceptionInfo);
|
||||
|
@ -36,6 +36,17 @@ namespace Utils
|
||||
LocalFree(messageBuffer);
|
||||
}
|
||||
|
||||
std::string GetLastWindowsError()
|
||||
{
|
||||
DWORD errorMessageID = ::GetLastError();
|
||||
LPSTR messageBuffer = nullptr;
|
||||
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
nullptr, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<LPSTR>(&messageBuffer), 0, nullptr);
|
||||
std::string message(messageBuffer, size);
|
||||
LocalFree(messageBuffer);
|
||||
return message;
|
||||
}
|
||||
|
||||
bool IsWineEnvironment()
|
||||
{
|
||||
HMODULE hntdll = GetModuleHandleA("ntdll.dll");
|
||||
|
@ -5,6 +5,7 @@ namespace Utils
|
||||
std::string GetMimeType(std::string url);
|
||||
std::string ParseChallenge(std::string data);
|
||||
void OutputDebugLastError();
|
||||
std::string GetLastWindowsError();
|
||||
|
||||
bool IsWineEnvironment();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user