crash logging

This commit is contained in:
rei-2
2024-10-26 07:55:26 -04:00
parent cc571954e8
commit 52117cb7a0
8 changed files with 161 additions and 105 deletions
+2 -2
View File
@@ -564,11 +564,11 @@
<ClCompile Include="src\SDK\Helpers\TraceFilters\TraceFilters.cpp" />
<ClCompile Include="src\SDK\SDK.cpp" />
<ClCompile Include="src\Utils\ConVars\ConVars.cpp" />
<ClCompile Include="src\Utils\CrashLog\CrashLog.cpp" />
<ClCompile Include="src\Utils\Hooks\Hooks.cpp" />
<ClCompile Include="src\Utils\Interfaces\Interfaces.cpp" />
<ClCompile Include="src\Utils\KeyHandler\KeyHandler.cpp" />
<ClCompile Include="src\Utils\Memory\Memory.cpp" />
<ClCompile Include="src\Utils\Minidump\Minidump.cpp" />
<ClCompile Include="src\Utils\NetVars\NetVars.cpp" />
<ClCompile Include="src\Utils\Signatures\Signatures.cpp" />
<ClCompile Include="src\Utils\Timer\Timer.cpp" />
@@ -826,6 +826,7 @@
<ClInclude Include="src\SDK\Vars.h" />
<ClInclude Include="src\Utils\Assert\Assert.h" />
<ClInclude Include="src\Utils\ConVars\ConVars.h" />
<ClInclude Include="src\Utils\CrashLog\CrashLog.h" />
<ClInclude Include="src\Utils\Feature\Feature.h" />
<ClInclude Include="src\Utils\Hash\FNV1A.h" />
<ClInclude Include="src\Utils\Hooks\Hooks.h" />
@@ -833,7 +834,6 @@
<ClInclude Include="src\Utils\KeyHandler\KeyHandler.h" />
<ClInclude Include="src\Utils\Math\Math.h" />
<ClInclude Include="src\Utils\Memory\Memory.h" />
<ClInclude Include="src\Utils\Minidump\Minidump.h" />
<ClInclude Include="src\Utils\NetVars\NetVars.h" />
<ClInclude Include="src\Utils\Signatures\Signatures.h" />
<ClInclude Include="src\Utils\Timer\Timer.h" />
+2 -2
View File
@@ -22,7 +22,6 @@
<ClCompile Include="src\Utils\Interfaces\Interfaces.cpp" />
<ClCompile Include="src\Utils\KeyHandler\KeyHandler.cpp" />
<ClCompile Include="src\Utils\Memory\Memory.cpp" />
<ClCompile Include="src\Utils\Minidump\Minidump.cpp" />
<ClCompile Include="src\Utils\NetVars\NetVars.cpp" />
<ClCompile Include="src\Utils\Signatures\Signatures.cpp" />
<ClCompile Include="src\Utils\Timer\Timer.cpp" />
@@ -172,6 +171,7 @@
<ClCompile Include="src\Hooks\CTFGCClientSystem_UpdateAssignedLobby.cpp" />
<ClCompile Include="src\Hooks\CTFBadgePanel_SetupBadge.cpp" />
<ClCompile Include="src\Hooks\IEngineTrace_TraceRay.cpp" />
<ClCompile Include="src\Utils\CrashLog\CrashLog.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Utils\UtlVector\UtlVector.h" />
@@ -301,7 +301,6 @@
<ClInclude Include="src\Utils\KeyHandler\KeyHandler.h" />
<ClInclude Include="src\Utils\Math\Math.h" />
<ClInclude Include="src\Utils\Memory\Memory.h" />
<ClInclude Include="src\Utils\Minidump\Minidump.h" />
<ClInclude Include="src\Utils\NetVars\NetVars.h" />
<ClInclude Include="src\Utils\Signatures\Signatures.h" />
<ClInclude Include="src\Utils\Timer\Timer.h" />
@@ -438,6 +437,7 @@
<ClInclude Include="src\SDK\Definitions\Main\CCaptureFlag.h" />
<ClInclude Include="src\SDK\Definitions\Interfaces\IPanel.h" />
<ClInclude Include="src\SDK\Definitions\Interfaces\CTFGCClientSystem.h" />
<ClInclude Include="src\Utils\CrashLog\CrashLog.h" />
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />
+2 -8
View File
@@ -1,6 +1,6 @@
#include <Windows.h>
#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<HMODULE>(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);
+6 -8
View File
@@ -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
+142
View File
@@ -0,0 +1,142 @@
#include "CrashLog.h"
#include "../../Features/Configs/Configs.h"
#include <ImageHlp.h>
#include <deque>
#include <sstream>
#include <fstream>
#include <format>
#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<Frame> 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<Frame> 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;
}
+7
View File
@@ -0,0 +1,7 @@
#pragma once
#include <Windows.h>
namespace CrashLog
{
LONG APIENTRY ExceptionFilter(PEXCEPTION_POINTERS Info);
}
-77
View File
@@ -1,77 +0,0 @@
#include "Minidump.h"
#include <dbghelp.h>
#include <shlobj.h>
#include <tchar.h>
#include <ctime>
[[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<decltype(&MiniDumpWriteDump)>(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<int>(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);
}
-8
View File
@@ -1,8 +0,0 @@
#pragma once
#include "../Feature/Feature.h"
#include <Windows.h>
namespace Minidump
{
LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS exPtr);
}