mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-05 08:25:32 +00:00
99 lines
3.5 KiB
C++
99 lines
3.5 KiB
C++
#include "pch.h"
|
|
|
|
#pragma warning(disable:4091) // dbghelp.h in Win8.1 has unnamed typedef'd enums
|
|
#include <dbghelp.h>
|
|
#pragma warning(default:4091)
|
|
|
|
typedef BOOL
|
|
(WINAPI *PMiniDumpWriteDump)(
|
|
IN HANDLE hProcess,
|
|
IN DWORD ProcessId,
|
|
IN HANDLE hFile,
|
|
IN MINIDUMP_TYPE DumpType,
|
|
IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
|
|
IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
|
|
IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
|
|
);
|
|
|
|
DWORD ExceptionMessage(LPSTR Proc, LPEXCEPTION_POINTERS ep) {
|
|
#ifndef _DEBUG
|
|
UNREFERENCED_PARAMETER(Proc);
|
|
#endif
|
|
|
|
MINIDUMP_EXCEPTION_INFORMATION mei;
|
|
char filename[MAX_PATH], temppath[MAX_PATH];
|
|
if (GetTempPath(MAX_PATH, temppath) == 0 ||
|
|
GetTempFileName(temppath, "kmc", 0, filename) == 0) {
|
|
OutputThreadDebugString("Minidump failed to generate temp file name\n");
|
|
}
|
|
else {
|
|
HANDLE hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
|
|
if (!hFile) {
|
|
OutputThreadDebugString("Minidump failed to create file ");
|
|
OutputThreadDebugString(filename);
|
|
}
|
|
else {
|
|
mei.ClientPointers = TRUE;
|
|
mei.ExceptionPointers = ep;
|
|
mei.ThreadId = GetCurrentThreadId();
|
|
HMODULE hDbgHelp = LoadLibrary("dbghelp.dll");
|
|
if (!hDbgHelp) {
|
|
OutputThreadDebugString("dbghelp.dll not available");
|
|
}
|
|
else {
|
|
PMiniDumpWriteDump mdwd = (PMiniDumpWriteDump) GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
|
|
if (!mdwd) {
|
|
OutputThreadDebugString("MiniDumpWriteDump not available");
|
|
}
|
|
else {
|
|
if (!(*mdwd)(GetCurrentProcess(), GetCurrentProcessId(), hFile,
|
|
(MINIDUMP_TYPE)(MiniDumpWithDataSegs | MiniDumpWithHandleData),
|
|
&mei, NULL, NULL)) {
|
|
DebugLastError("MiniDumpWriteDump");
|
|
}
|
|
else {
|
|
OutputThreadDebugString("Minidump written to ");
|
|
OutputThreadDebugString(filename);
|
|
HKEY hkey;
|
|
if(RegCreateKeyEx(HKEY_CURRENT_USER, REGSZ_KeymanEngineDiag, 0, NULL, 0, KEY_ALL_ACCESS,
|
|
NULL, &hkey, NULL) == ERROR_SUCCESS) {
|
|
DWORD v = 0;
|
|
RegSetValueEx(hkey, filename, 0, REG_DWORD, (PBYTE)&v, sizeof(DWORD));
|
|
RegCloseKey(hkey);
|
|
}
|
|
}
|
|
}
|
|
FreeLibrary(hDbgHelp);
|
|
}
|
|
CloseHandle(hFile);
|
|
}
|
|
}
|
|
|
|
if(!ep || !ep->ExceptionRecord) {
|
|
OutputThreadDebugString("CAUGHT UNKNOWN EXCEPTION");
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|
|
LPEXCEPTION_RECORD er = ep->ExceptionRecord;
|
|
|
|
while(er != NULL) {
|
|
if (er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
|
|
OutputThreadDebugString("EXCEPTION_ACCESS_VIOLATION in ");
|
|
OutputThreadDebugString(Proc);
|
|
/*SendDebugMessageFormat(0, sdmGlobal, 0, "CAUGHT EXCEPTION %d (ACCESS VIOLATION) IN %s AT %x; attempted to %s %x",
|
|
er->ExceptionCode, Proc, er->ExceptionAddress,
|
|
er->ExceptionInformation[0] == 0 ? "read from" : "write to",
|
|
er->ExceptionInformation[1]);*/
|
|
}
|
|
else {
|
|
OutputThreadDebugString("CAUGHT EXCEPTION");
|
|
/*SendDebugMessageFormat(0, sdmGlobal, 0, "CAUGHT EXCEPTION %d IN %s AT %x",
|
|
er->ExceptionCode, Proc, er->ExceptionAddress);*/
|
|
}
|
|
er = er->ExceptionRecord;
|
|
}
|
|
|
|
//StackWalker sw(StackWalker::RetrieveModuleInfo | StackWalker::RetrieveFileVersion, NULL, GetCurrentProcessId(), GetCurrentProcess());
|
|
//sw.ShowCallstack(GetCurrentThread(), ep->ContextRecord);
|
|
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|