FluentUI/example/src/app_dmp.h

90 lines
3.3 KiB
C
Raw Normal View History

2024-04-11 14:51:43 +08:00
#pragma once
2024-01-04 18:00:44 +08:00
#include <Windows.h>
#include <DbgHelp.h>
#include <QDateTime>
#include <QDir>
#include <QGuiApplication>
#include <QProcess>
#include <QStandardPaths>
#include <QString>
#pragma comment(lib, "Dbghelp.lib")
2024-06-28 17:09:23 +08:00
static void miniDumpWriteDump(HANDLE hProcess, DWORD ProcessId, HANDLE hFile,
CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam) {
typedef HRESULT(WINAPI * MiniDumpWriteDumpPtr)(
HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType,
CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
2024-01-04 18:46:33 +08:00
HMODULE module = LoadLibraryW(L"Dbghelp.dll");
2024-04-11 14:51:43 +08:00
if (module) {
2024-01-04 18:46:33 +08:00
MiniDumpWriteDumpPtr mini_dump_write_dump;
2024-06-28 17:09:23 +08:00
mini_dump_write_dump =
reinterpret_cast<MiniDumpWriteDumpPtr>(GetProcAddress(module, "MiniDumpWriteDump"));
2024-04-11 14:51:43 +08:00
if (mini_dump_write_dump) {
2024-06-28 17:09:23 +08:00
mini_dump_write_dump(hProcess, ProcessId, hFile, static_cast<MINIDUMP_TYPE>(80),
ExceptionParam, nullptr, CallbackParam);
2024-01-04 18:46:33 +08:00
}
}
}
2024-06-28 17:09:23 +08:00
BOOL CALLBACK MyMiniDumpCallback(PVOID, const PMINIDUMP_CALLBACK_INPUT input,
PMINIDUMP_CALLBACK_OUTPUT output) {
2024-04-11 14:51:43 +08:00
if (input == nullptr || output == nullptr)
2024-01-04 18:00:44 +08:00
return FALSE;
BOOL ret = FALSE;
switch (input->CallbackType) {
2024-04-11 14:51:43 +08:00
case IncludeModuleCallback:
case IncludeThreadCallback:
case ThreadCallback:
case ThreadExCallback:
ret = TRUE;
break;
case ModuleCallback: {
if (!(output->ModuleWriteFlags & ModuleReferencedByMemory)) {
output->ModuleWriteFlags &= ~ModuleWriteModule;
}
ret = TRUE;
2024-06-28 17:09:23 +08:00
} break;
2024-04-11 14:51:43 +08:00
default:
break;
2024-01-04 18:00:44 +08:00
}
return ret;
}
2024-04-11 14:51:43 +08:00
void WriteDump(EXCEPTION_POINTERS *exp, const std::wstring &path) {
2024-06-28 17:09:23 +08:00
HANDLE h = ::CreateFileW(path.c_str(), GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, nullptr);
2024-01-04 18:00:44 +08:00
MINIDUMP_EXCEPTION_INFORMATION info;
info.ThreadId = ::GetCurrentThreadId();
info.ExceptionPointers = exp;
2024-01-04 18:46:33 +08:00
info.ClientPointers = FALSE;
2024-01-04 18:00:44 +08:00
MINIDUMP_CALLBACK_INFORMATION mci;
2024-04-11 14:51:43 +08:00
mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE) MyMiniDumpCallback;
mci.CallbackParam = nullptr;
miniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), h, &info, &mci);
2024-01-04 18:00:44 +08:00
::CloseHandle(h);
}
2024-04-11 14:51:43 +08:00
LONG WINAPI MyUnhandledExceptionFilter(EXCEPTION_POINTERS *exp) {
2024-06-28 17:09:23 +08:00
const QString dumpFileName =
QString("%1_%2.dmp").arg("crash", QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss"));
const QString dumpDirPath =
QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/dmp";
2024-01-04 18:00:44 +08:00
const QDir dumpDir(dumpDirPath);
2024-04-11 14:51:43 +08:00
if (!dumpDir.exists()) {
2024-01-04 18:00:44 +08:00
dumpDir.mkpath(dumpDirPath);
}
QString dumpFilePath = dumpDir.filePath(dumpFileName);
WriteDump(exp, dumpFilePath.toStdWString());
QStringList arguments;
arguments << "-crashed=" + dumpFilePath;
2024-04-11 14:51:43 +08:00
QProcess::startDetached(QGuiApplication::applicationFilePath(), arguments);
2024-01-04 18:00:44 +08:00
return EXCEPTION_EXECUTE_HANDLER;
2024-06-28 17:09:23 +08:00
}