r5sdk/r5dev/public/tier0/crashhandler.h
Kawe Mazidjatari 6434b8abe9 Tier0: crash handler refactor & bug fix
Fix syntax error on page protection flags check when determining whether we encountered a return address. Also limit the amount of dynamic memory allocation calls, offer a large enough static buffer where we can just write into when we crash without needing to alloc or realloc anything. Also removed some hacky code like the whitelist set, and made the module handle array static into the class as well. The CrashHandler singleton is now a static class instance.
2024-04-05 17:56:51 +02:00

118 lines
3.4 KiB
C++

#ifndef CRASHHANDLER_H
#define CRASHHANDLER_H
#include "tier1/fmtstr.h"
#define CRASHMESSAGE_MSG_EXECUTABLE "bin\\crashmsg.exe"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CCrashHandler
{
public:
CCrashHandler();
~CCrashHandler();
void Init();
void Shutdown();
void Reset();
//-------------------------------------------------------------------------
// Inlines:
//-------------------------------------------------------------------------
void Start();
void End();
inline void SetExit(const bool bExit) { m_bExit = bExit; };
inline bool GetExit() const { return m_bExit; };
inline bool IsValid() const { return m_hExceptionHandler != nullptr; };
//-------------------------------------------------------------------------
// Formatters:
//-------------------------------------------------------------------------
void FormatCrash();
void FormatCallstack();
void FormatRegisters();
void FormatModules();
void FormatSystemInfo();
void FormatBuildInfo();
//-------------------------------------------------------------------------
// Utility:
//-------------------------------------------------------------------------
const char* ExceptionToString() const;
const char* ExceptionToString(const DWORD nExceptionCode) const;
void SetExceptionPointers(EXCEPTION_POINTERS* const pExceptionPointers) { m_pExceptionPointers = pExceptionPointers; }
void SetCrashCallback(PVOID pCrashCallback) { m_pCrashCallback = pCrashCallback; }
void CaptureCallStack();
void WriteFile();
void CreateMessageProcess();
void CrashCallback();
private:
//-------------------------------------------------------------------------
// Internals:
//-------------------------------------------------------------------------
void FormatExceptionAddress();
void FormatExceptionAddress(const LPCSTR pExceptionAddress);
void FormatExceptionCode();
void FormatALU(const char* const pszRegister, const DWORD64 nContent);
void FormatFPU(const char* const pszRegister, const M128A* const pxContent);
bool IsPageAccessible() const;
private:
enum
{
NUM_FRAMES_TO_CAPTURE = 128,
MAX_MODULE_HANDLES = 4096
};
// Captured callstack frames.
PVOID m_ppStackTrace[NUM_FRAMES_TO_CAPTURE];
WORD m_nCapturedFrames;
// The loaded module handles that are being tracked.
HMODULE m_ppModuleHandles[MAX_MODULE_HANDLES];
// Custom crash callback that's called after the logs have been written.
PVOID m_pCrashCallback;
// Current exception handler, only kept here for tracking as we need the
// handle if we want to remove this handler.
PVOID m_hExceptionHandler;
EXCEPTION_POINTERS* m_pExceptionPointers;
// 32KiB buffer containing the entire crash log, static as we shouldn't
// allocate any dynamic memory when writing the log files as that is
// unsafe during a crash.
CFmtStrQuietTruncationN<32768> m_Buffer;
// Buffer containing the module name we crashed in.
CFmtStrQuietTruncationN<256> m_CrashingModule;
// Buffer containing cmd line arguments for the external crash message
// process.
CFmtStrQuietTruncationN<256> m_MessageCmdLine;
uint8_t m_nCrashMsgFlags;
// Set when called to prevent recursive calls.
bool m_bExit;
// Set when crashmsg.exe is created to prevent recursive messages.
bool m_bMessageCreated;
mutable RTL_SRWLOCK m_Lock;
};
extern CCrashHandler g_CrashHandler;
#endif // CRASHHANDLER_H