Skip to content

Commit

Permalink
RMG: add minidump handler in main.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
Rosalie241 committed Feb 27, 2025
1 parent d5af42a commit f01d0ce
Showing 1 changed file with 79 additions and 2 deletions.
81 changes: 79 additions & 2 deletions Source/RMG/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
#include <iostream>
#include <cstdlib>

#ifndef _WIN32
#ifdef _WIN32
#include <Windows.h>
#include <wchar.h>
#else
#include <signal.h>
#endif

Expand All @@ -42,10 +45,79 @@ static void message_handler(QtMsgType type, const QMessageLogContext &context, c
std::cerr << msg.toStdString() << std::endl;
}

#ifdef _WIN32
typedef BOOL (WINAPI* ptr_MiniDumpWriteDump)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE,
PMINIDUMP_EXCEPTION_INFORMATION,
PMINIDUMP_USER_STREAM_INFORMATION,
PMINIDUMP_CALLBACK_INFORMATION);
static void show_error(const char* error)
{
MessageBoxA(nullptr, error, "RMG Crash Handler", MB_OK | MB_ICONERROR);
}

static LONG WINAPI exception_handler(_EXCEPTION_POINTERS* ExceptionInfo)
{
HMODULE dbgHelpModule = LoadLibraryA("Dbghelp.dll");
if (dbgHelpModule == nullptr)
{
show_error("Failed to find Dbghelp.dll!");
return EXCEPTION_CONTINUE_SEARCH;
}

ptr_MiniDumpWriteDump miniDumpWriteDump =
(ptr_MiniDumpWriteDump)GetProcAddress(dbgHelpModule, "MiniDumpWriteDump");
if (miniDumpWriteDump == nullptr)
{
show_error("Failed to retrieve MiniDumpWriteDump from Dbghelp.dll!");
return EXCEPTION_CONTINUE_SEARCH;
}

wchar_t dump_filename[MAX_PATH+1] = {0};
DWORD filename_len = GetModuleFileNameW(nullptr, dump_filename, MAX_PATH);
if (filename_len <= 0)
{
show_error("Failed to retrieve path of current process!");
return EXCEPTION_CONTINUE_SEARCH;
}

if (filename_len >= MAX_PATH)
{ // replace .exe with .dmp
wcscpy((dump_filename + (filename_len - 4)), ".dmp");
}
else
{ // append .dmp to .exe
wcscpy((dump_filename + filename_len), ".dmp");
}

HANDLE hDumpFile = CreateFileW(dump_filename, GENERIC_WRITE, FILE_SHARE_WRITE,
nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);

if (hDumpFile != INVALID_HANDLE_VALUE)
{
_MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
exceptionInfo.ThreadId = GetCurrentThreadId();
exceptionInfo.ExceptionPointers = pExceptionInfo;
exceptionInfo.ClientPointers = nullptr;

BOOL ret = miniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hDumpFile, MiniDumpNormal, &exceptionInfo,
nullptr, nullptr);
if (!ret)
{
show_error("Crash detected, failed to save minidump file!");
}
}

// we've saved the minidump,
// now we can crash safely
return EXCEPTION_CONTINUE_SEARCH;
}
#else
static void signal_handler(int sig)
{
QGuiApplication::quit();
}
#endif // _WIN32

//
// Exported Functions
Expand All @@ -56,7 +128,12 @@ int main(int argc, char **argv)
// install message handler
qInstallMessageHandler(message_handler);

#ifndef _WIN32
#ifdef _WIN32
// on Windows, to aid with crash debugging
// we'll install a crash handler and
// write out a minidump there
SetUnhandledExceptionFilter(exception_handler);
#else
// on Linux we need to install signal handlers,
// so we can exit cleanly when the user presses
// i.e control+c
Expand Down

0 comments on commit f01d0ce

Please sign in to comment.