crash reports are functional on windows

This commit is contained in:
itsmattkc
2019-05-10 13:11:45 +10:00
parent 3fe0d1cda5
commit 7985cc48d4
8 changed files with 318 additions and 36 deletions
+88 -2
View File
@@ -22,7 +22,12 @@
#include <QMessageBox>
#ifdef __GNUC__
#ifdef Q_OS_WIN
#include <windows.h>
#include <DbgHelp.h>
#elif defined(Q_OS_LINUX)
#include <execinfo.h>
#endif
#include <signal.h>
#include <unistd.h>
#endif
@@ -43,6 +48,81 @@ extern "C" {
#ifdef __GNUC__
void handler(int sig) {
QStringList strings;
#ifdef Q_OS_WIN
HANDLE process = GetCurrentProcess();
HANDLE thread = GetCurrentThread();
CONTEXT context;
memset(&context, 0, sizeof(CONTEXT));
context.ContextFlags = CONTEXT_FULL;
RtlCaptureContext(&context);
SymInitialize(process, NULL, TRUE);
DWORD image;
STACKFRAME64 stackframe;
ZeroMemory(&stackframe, sizeof(STACKFRAME64));
#ifdef _M_IX86
image = IMAGE_FILE_MACHINE_I386;
stackframe.AddrPC.Offset = context.Eip;
stackframe.AddrPC.Mode = AddrModeFlat;
stackframe.AddrFrame.Offset = context.Ebp;
stackframe.AddrFrame.Mode = AddrModeFlat;
stackframe.AddrStack.Offset = context.Esp;
stackframe.AddrStack.Mode = AddrModeFlat;
#elif _M_X64
image = IMAGE_FILE_MACHINE_AMD64;
stackframe.AddrPC.Offset = context.Rip;
stackframe.AddrPC.Mode = AddrModeFlat;
stackframe.AddrFrame.Offset = context.Rsp;
stackframe.AddrFrame.Mode = AddrModeFlat;
stackframe.AddrStack.Offset = context.Rsp;
stackframe.AddrStack.Mode = AddrModeFlat;
#elif _M_IA64
image = IMAGE_FILE_MACHINE_IA64;
stackframe.AddrPC.Offset = context.StIIP;
stackframe.AddrPC.Mode = AddrModeFlat;
stackframe.AddrFrame.Offset = context.IntSp;
stackframe.AddrFrame.Mode = AddrModeFlat;
stackframe.AddrBStore.Offset = context.RsBSP;
stackframe.AddrBStore.Mode = AddrModeFlat;
stackframe.AddrStack.Offset = context.IntSp;
stackframe.AddrStack.Mode = AddrModeFlat;
#endif
int counter = 0;
QString line_template = "[%1] %2";
while (StackWalk64(
image, process, thread,
&stackframe, &context, NULL,
SymFunctionTableAccess64, SymGetModuleBase64, NULL)) {
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
symbol->MaxNameLen = MAX_SYM_NAME;
DWORD64 displacement = 0;
QString sym_name;
if (SymFromAddr(process, stackframe.AddrPC.Offset, &displacement, symbol)) {
sym_name = symbol->Name;
} else {
sym_name = "???";
}
QString s = line_template.arg(QString::number(counter), sym_name);
strings.append(s);
qDebug() << s;
counter++;
}
SymCleanup(process);
#elif defined(Q_OS_LINUX)
void *array[10];
size_t size;
@@ -55,10 +135,16 @@ void handler(int sig) {
// try to show a GUI crash report
char** bt_syms = backtrace_symbols(array, size);
olive::crash_dialog->SetData(sig, bt_syms, size);
olive::crash_dialog->exec();
for (int i=0;i<size;i++) {
strings.append(bt_syms[i]);
}
free(bt_syms);
#endif
olive::crash_dialog->SetData(sig, strings);
olive::crash_dialog->exec();
abort();
}
#endif