From 52117cb7a06d14c1634df9eabd00920d2dcc20cf Mon Sep 17 00:00:00 2001
From: rei-2 <174158077+rei-2@users.noreply.github.com>
Date: Sat, 26 Oct 2024 07:55:26 -0400
Subject: [PATCH] crash logging
---
Amalgam/Amalgam.vcxproj | 4 +-
Amalgam/Amalgam.vcxproj.filters | 4 +-
Amalgam/src/DllMain.cpp | 10 +-
Amalgam/src/SDK/Vars.h | 14 +--
Amalgam/src/Utils/CrashLog/CrashLog.cpp | 142 ++++++++++++++++++++++++
Amalgam/src/Utils/CrashLog/CrashLog.h | 7 ++
Amalgam/src/Utils/Minidump/Minidump.cpp | 77 -------------
Amalgam/src/Utils/Minidump/Minidump.h | 8 --
8 files changed, 161 insertions(+), 105 deletions(-)
create mode 100644 Amalgam/src/Utils/CrashLog/CrashLog.cpp
create mode 100644 Amalgam/src/Utils/CrashLog/CrashLog.h
delete mode 100644 Amalgam/src/Utils/Minidump/Minidump.cpp
delete mode 100644 Amalgam/src/Utils/Minidump/Minidump.h
diff --git a/Amalgam/Amalgam.vcxproj b/Amalgam/Amalgam.vcxproj
index ff72cc5c..88878c2d 100644
--- a/Amalgam/Amalgam.vcxproj
+++ b/Amalgam/Amalgam.vcxproj
@@ -564,11 +564,11 @@
+
-
@@ -826,6 +826,7 @@
+
@@ -833,7 +834,6 @@
-
diff --git a/Amalgam/Amalgam.vcxproj.filters b/Amalgam/Amalgam.vcxproj.filters
index e2686880..594ff40c 100644
--- a/Amalgam/Amalgam.vcxproj.filters
+++ b/Amalgam/Amalgam.vcxproj.filters
@@ -22,7 +22,6 @@
-
@@ -172,6 +171,7 @@
+
@@ -301,7 +301,6 @@
-
@@ -438,6 +437,7 @@
+
diff --git a/Amalgam/src/DllMain.cpp b/Amalgam/src/DllMain.cpp
index 2807db9c..beac23c0 100644
--- a/Amalgam/src/DllMain.cpp
+++ b/Amalgam/src/DllMain.cpp
@@ -1,6 +1,6 @@
#include
#include "Core/Core.h"
-#include "Utils/Minidump/Minidump.h"
+#include "Utils/CrashLog/CrashLog.h"
DWORD WINAPI MainThread(LPVOID lpParam)
{
@@ -8,10 +8,6 @@ DWORD WINAPI MainThread(LPVOID lpParam)
U::Core.Loop();
U::Core.Unload();
-#ifndef _DEBUG
- SetUnhandledExceptionFilter(nullptr);
-#endif
-
FreeLibraryAndExitThread(static_cast(lpParam), EXIT_SUCCESS);
}
@@ -20,9 +16,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
-#ifndef _DEBUG
- SetUnhandledExceptionFilter(Minidump::ExceptionFilter);
-#endif
+ AddVectoredExceptionHandler(1, CrashLog::ExceptionFilter);
if (const auto hMainThread = CreateThread(nullptr, 0, MainThread, hinstDLL, 0, nullptr))
CloseHandle(hMainThread);
diff --git a/Amalgam/src/SDK/Vars.h b/Amalgam/src/SDK/Vars.h
index 34492d70..1d06e3d2 100644
--- a/Amalgam/src/SDK/Vars.h
+++ b/Amalgam/src/SDK/Vars.h
@@ -108,8 +108,6 @@ namespace Vars
SUBNAMESPACE_BEGIN(Theme)
CVar(Accent, Color_t(255, 101, 101, 255), VISUAL)
CVar(Background, Color_t(23, 23, 23, 250), VISUAL)
- CVar(Foreground, Color_t(11, 11, 11, 250), VISUAL)
- CVar(Foremost, Color_t(23, 23, 23, 250), VISUAL)
CVar(Inactive, Color_t(150, 150, 150, 255), VISUAL)
CVar(Active, Color_t(255, 255, 255, 255), VISUAL)
SUBNAMESPACE_END(Theme)
@@ -156,17 +154,17 @@ namespace Vars
CVar(SplashRadius, 90.f)
CVar(AutoRelease, 0.f)
- CVar(GroundSamples, 66, NOSAVE) // debug
+ CVar(GroundSamples, 33, NOSAVE) // debug
CVar(GroundStraightFuzzyValue, 100.f, NOSAVE) // debug
- CVar(GroundLowMinimumSamples, 5, NOSAVE) // debug
- CVar(GroundHighMinimumSamples, 15, NOSAVE) // debug
+ CVar(GroundLowMinimumSamples, 8, NOSAVE) // debug
+ CVar(GroundHighMinimumSamples, 16, NOSAVE) // debug
CVar(GroundLowMinimumDistance, 0.f, NOSAVE) // debug
CVar(GroundHighMinimumDistance, 2500.f, NOSAVE) // debug
- CVar(AirSamples, 66, NOSAVE) // debug
+ CVar(AirSamples, 33, NOSAVE) // debug
CVar(AirStraightFuzzyValue, 10.f, NOSAVE) // debug
- CVar(AirLowMinimumSamples, 5, NOSAVE) // debug
- CVar(AirHighMinimumSamples, 5, NOSAVE) // debug
+ CVar(AirLowMinimumSamples, 3, NOSAVE) // debug
+ CVar(AirHighMinimumSamples, 3, NOSAVE) // debug
CVar(AirLowMinimumDistance, 100000.f, NOSAVE) // debug
CVar(AirHighMinimumDistance, 100000.f, NOSAVE) // debug
diff --git a/Amalgam/src/Utils/CrashLog/CrashLog.cpp b/Amalgam/src/Utils/CrashLog/CrashLog.cpp
new file mode 100644
index 00000000..aaed317d
--- /dev/null
+++ b/Amalgam/src/Utils/CrashLog/CrashLog.cpp
@@ -0,0 +1,142 @@
+#include "CrashLog.h"
+
+#include "../../Features/Configs/Configs.h"
+
+#include
+#include
+#include
+#include
+#include
+#pragma comment(lib, "imagehlp.lib")
+
+struct Frame
+{
+ std::string m_sModule = "";
+ uintptr_t m_pAddress = 0;
+ std::string m_sFile = "";
+ unsigned int m_uLine = 0;
+ std::string m_sName = "";
+};
+
+static std::deque StackTrace(PCONTEXT context)
+{
+ HANDLE hProcess = GetCurrentProcess();
+ HANDLE hThread = GetCurrentThread();
+
+ OutputDebugStringA("StackTrace\n");
+ if (!SymInitialize(hProcess, nullptr, TRUE))
+ return {};
+
+ OutputDebugStringA("Frame\n");
+ SymSetOptions(SYMOPT_LOAD_LINES);
+
+ STACKFRAME64 frame = {};
+ frame.AddrPC.Offset = context->Rip;
+ frame.AddrFrame.Offset = context->Rbp;
+ frame.AddrStack.Offset = context->Rsp;
+ frame.AddrPC.Mode = AddrModeFlat;
+ frame.AddrFrame.Mode = AddrModeFlat;
+ frame.AddrStack.Mode = AddrModeFlat;
+
+ std::deque vTrace = {};
+ while (StackWalk64(IMAGE_FILE_MACHINE_AMD64, hProcess, hThread, &frame, context, nullptr, SymFunctionTableAccess64, SymGetModuleBase64, nullptr))
+ {
+ OutputDebugStringA("StackWalk\n");
+ Frame tFrame = {};
+
+ tFrame.m_pAddress = frame.AddrPC.Offset;
+
+ {
+ auto base = HINSTANCE(SymGetModuleBase64(hProcess, frame.AddrPC.Offset));
+ char buf[MAX_PATH];
+ if (base && GetModuleFileNameA(base, buf, MAX_PATH))
+ {
+ tFrame.m_sModule = std::format("{}, {:#x}", buf, uintptr_t(base));
+ auto find = tFrame.m_sModule.rfind("\\");
+ if (find != std::string::npos)
+ tFrame.m_sModule.replace(0, find + 1, "");
+ }
+ }
+
+ {
+ DWORD offset = 0;
+ IMAGEHLP_LINE64 line = {};
+ line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
+ if (SymGetLineFromAddr64(hProcess, frame.AddrPC.Offset, &offset, &line))
+ {
+ tFrame.m_sFile = line.FileName;
+ tFrame.m_uLine = line.LineNumber;
+ auto find = tFrame.m_sFile.rfind("\\");
+ if (find != std::string::npos)
+ tFrame.m_sFile.replace(0, find + 1, "");
+ }
+ }
+
+ {
+ uintptr_t offset = 0;
+ char buf[sizeof(IMAGEHLP_SYMBOL64) + 255];
+ auto symbol = PIMAGEHLP_SYMBOL64(buf);
+ symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64) + 255;
+ symbol->MaxNameLength = 254;
+ if (SymGetSymFromAddr64(hProcess, frame.AddrPC.Offset, &offset, symbol))
+ tFrame.m_sName = symbol->Name;
+ }
+
+ vTrace.push_back(tFrame);
+ }
+ //if (!vTrace.empty())
+ // vTrace.pop_front();
+
+ SymCleanup(hProcess);
+
+ return vTrace;
+}
+
+LONG APIENTRY CrashLog::ExceptionFilter(PEXCEPTION_POINTERS Info)
+{
+ if (Info->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
+ return EXCEPTION_EXECUTE_HANDLER;
+
+ std::stringstream error;
+ error << std::format("Error: {:#X}\n", Info->ExceptionRecord->ExceptionCode);
+ error << std::format("Address: {:#X}\n\n", uintptr_t(Info->ExceptionRecord->ExceptionAddress));
+ error << std::format("RIP: {:#x}\n", Info->ContextRecord->Rip);
+ error << std::format("EFLAGS: {:#x}\n", Info->ContextRecord->EFlags);
+ error << std::format("RAX: {:#x}\n", Info->ContextRecord->Rax);
+ error << std::format("RCX: {:#x}\n", Info->ContextRecord->Rcx);
+ error << std::format("RDX: {:#x}\n", Info->ContextRecord->Rdx);
+ error << std::format("RBX: {:#x}\n", Info->ContextRecord->Rbx);
+ error << std::format("RSP: {:#x}\n", Info->ContextRecord->Rsp);
+ error << std::format("RBP: {:#x}\n", Info->ContextRecord->Rbp);
+ error << std::format("RSI: {:#x}\n", Info->ContextRecord->Rsi);
+ error << std::format("RDI: {:#x}\n\n", Info->ContextRecord->Rdi);
+
+ auto vTrace = StackTrace(Info->ContextRecord);
+ if (!vTrace.empty())
+ {
+ for (auto& tFrame : vTrace)
+ {
+ error << std::format("{:#x}", tFrame.m_pAddress);
+ if (!tFrame.m_sModule.empty())
+ error << std::format(" ({})", tFrame.m_sModule);
+ if (!tFrame.m_sFile.empty())
+ error << std::format(" ({} L{})", tFrame.m_sFile, tFrame.m_uLine);
+ if (!tFrame.m_sName.empty())
+ error << std::format(" ({})", tFrame.m_sName);
+ error << "\n";
+ }
+ error << "\n";
+ }
+
+ error << "Ctrl + C to copy. Logged to Amalgam\\crash_log.txt. ";
+
+ MessageBox(nullptr, error.str().c_str(), "Unhandled exception", MB_OK | MB_ICONERROR);
+
+ error << "\n\n\n\n";
+ std::ofstream file;
+ file.open(F::Configs.sConfigPath + "\\crash_log.txt", std::ios_base::app);
+ file << error.str();
+ file.close();
+
+ return EXCEPTION_EXECUTE_HANDLER;
+}
\ No newline at end of file
diff --git a/Amalgam/src/Utils/CrashLog/CrashLog.h b/Amalgam/src/Utils/CrashLog/CrashLog.h
new file mode 100644
index 00000000..2d993214
--- /dev/null
+++ b/Amalgam/src/Utils/CrashLog/CrashLog.h
@@ -0,0 +1,7 @@
+#pragma once
+#include
+
+namespace CrashLog
+{
+ LONG APIENTRY ExceptionFilter(PEXCEPTION_POINTERS Info);
+}
\ No newline at end of file
diff --git a/Amalgam/src/Utils/Minidump/Minidump.cpp b/Amalgam/src/Utils/Minidump/Minidump.cpp
deleted file mode 100644
index 2f7bbe90..00000000
--- a/Amalgam/src/Utils/Minidump/Minidump.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-#include "Minidump.h"
-
-#include
-#include
-#include
-#include
-
-[[noreturn]] void ExitWithMessage(const TCHAR* msg)
-{
- MessageBox(
- nullptr,
- msg,
- _T("Unhandled exception"),
- MB_OK | MB_ICONERROR
- );
-
- ExitProcess(0);
-}
-
-LONG __stdcall Minidump::ExceptionFilter(PEXCEPTION_POINTERS exPtr)
-{
- const HMODULE hLib = LoadLibrary(_T("dbghelp"));
- if (!hLib)
- {
- ExitWithMessage(_T("Could not load dbghelp!"));
- }
-
- const auto pMiniDumpWriteDump = reinterpret_cast(GetProcAddress(hLib, "MiniDumpWriteDump"));
-
- // Get the MiniDumpWriteDump function
- if (!pMiniDumpWriteDump)
- {
- ExitWithMessage(_T("Could not load MiniDumpWriteDump!"));
- }
-
- // Get the dump folde (Desktop)
- TCHAR buf[512];
- const auto gfpResult = SHGetFolderPath(nullptr, CSIDL_DESKTOP, nullptr, SHGFP_TYPE_CURRENT, buf);
- if (FAILED(gfpResult))
- {
- ExitWithMessage(_T("Failed to get folder path!"));
- }
-
- // Create a file handle
- TCHAR fileName[MAX_PATH];
- const int curTime = static_cast(time(nullptr) % 100000);
- wsprintf(fileName, _T("%s\\Crash_Amalgam_%x.dmp"), buf, curTime);
- const HANDLE hFile = CreateFile(fileName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
-
- if (hFile == INVALID_HANDLE_VALUE)
- {
- wsprintf(buf, _T("Could not create minidump file!\n\n- Error: %ul\n- File: %s"), GetLastError(), fileName);
- ExitWithMessage(buf);
- }
-
- // Write the minidump
- MINIDUMP_EXCEPTION_INFORMATION mdei = {
- GetCurrentThreadId(),
- exPtr,
- FALSE
- };
-
- if (pMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &mdei, nullptr, nullptr))
- {
- wsprintf(buf, _T("Minidump created.\n\n- Build: " __TIMESTAMP__ "\n- File: %s"), fileName);
- }
- else
- {
- wsprintf(buf, _T("Could not create minidump!\n- Error: %ul\n- File: %s"), GetLastError(), fileName);
- }
-
- // Cleanup
- FreeLibrary(hLib);
- CloseHandle(hFile);
-
- ExitWithMessage(buf);
-}
\ No newline at end of file
diff --git a/Amalgam/src/Utils/Minidump/Minidump.h b/Amalgam/src/Utils/Minidump/Minidump.h
deleted file mode 100644
index 4a215c54..00000000
--- a/Amalgam/src/Utils/Minidump/Minidump.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-#include "../Feature/Feature.h"
-#include
-
-namespace Minidump
-{
- LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS exPtr);
-}
\ No newline at end of file