mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-05-09 20:40:33 +02:00
Attempt to get better logging from pure virtual call crashes
This commit is contained in:
parent
4e418f328f
commit
ff8d4883b1
4 changed files with 70 additions and 6 deletions
|
@ -10,15 +10,20 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAS_BUGSPLAT
|
|
||||||
#include "CrashReporter.h"
|
#include "CrashReporter.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <WinSock2.h>
|
||||||
#include <new.h>
|
#include <new.h>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#include <DbgHelp.h>
|
||||||
|
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include "Application.h"
|
||||||
|
|
||||||
|
|
||||||
|
#pragma comment(lib, "Dbghelp.lib")
|
||||||
|
|
||||||
// SetUnhandledExceptionFilter can be overridden by the CRT at the point that an error occurs. More information
|
// SetUnhandledExceptionFilter can be overridden by the CRT at the point that an error occurs. More information
|
||||||
// can be found here: http://www.codeproject.com/Articles/154686/SetUnhandledExceptionFilter-and-the-C-C-Runtime-Li
|
// can be found here: http://www.codeproject.com/Articles/154686/SetUnhandledExceptionFilter-and-the-C-C-Runtime-Li
|
||||||
|
@ -77,13 +82,43 @@ BOOL redirectLibraryFunctionToFunction(char* library, char* function, void* fn)
|
||||||
return bRet;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printStackTrace(ULONG framesToSkip = 1) {
|
||||||
|
QString result;
|
||||||
|
unsigned int i;
|
||||||
|
void * stack[100];
|
||||||
|
unsigned short frames;
|
||||||
|
SYMBOL_INFO * symbol;
|
||||||
|
HANDLE process;
|
||||||
|
|
||||||
|
process = GetCurrentProcess();
|
||||||
|
SymInitialize(process, NULL, TRUE);
|
||||||
|
frames = CaptureStackBackTrace(framesToSkip, 100, stack, NULL);
|
||||||
|
symbol = (SYMBOL_INFO *)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1);
|
||||||
|
symbol->MaxNameLen = 255;
|
||||||
|
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
|
|
||||||
|
for (i = 0; i < frames; i++) {
|
||||||
|
SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol);
|
||||||
|
qWarning() << QString("%1: %2 - 0x%0X").arg(QString::number(frames - i - 1), QString(symbol->Name), QString::number(symbol->Address, 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
free(symbol);
|
||||||
|
|
||||||
|
// Try to force the log to sync to the filesystem
|
||||||
|
auto app = qApp;
|
||||||
|
if (app && app->getLogger()) {
|
||||||
|
app->getLogger()->sync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void handleSignal(int signal) {
|
void handleSignal(int signal) {
|
||||||
// Throw so BugSplat can handle
|
// Throw so BugSplat can handle
|
||||||
throw(signal);
|
throw(signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handlePureVirtualCall() {
|
void __cdecl handlePureVirtualCall() {
|
||||||
|
qWarning() << "Pure virtual function call detected";
|
||||||
|
printStackTrace(2);
|
||||||
// Throw so BugSplat can handle
|
// Throw so BugSplat can handle
|
||||||
throw("ERROR: Pure virtual call");
|
throw("ERROR: Pure virtual call");
|
||||||
}
|
}
|
||||||
|
@ -107,6 +142,8 @@ _purecall_handler __cdecl noop_set_purecall_handler(_purecall_handler pNew) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAS_BUGSPLAT
|
||||||
|
|
||||||
static const DWORD BUG_SPLAT_FLAGS = MDSF_PREVENTHIJACKING | MDSF_USEGUARDMEMORY;
|
static const DWORD BUG_SPLAT_FLAGS = MDSF_PREVENTHIJACKING | MDSF_USEGUARDMEMORY;
|
||||||
|
|
||||||
CrashReporter::CrashReporter(QString bugSplatDatabase, QString bugSplatApplicationName, QString version)
|
CrashReporter::CrashReporter(QString bugSplatDatabase, QString bugSplatApplicationName, QString version)
|
||||||
|
@ -133,3 +170,4 @@ CrashReporter::CrashReporter(QString bugSplatDatabase, QString bugSplatApplicati
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
|
@ -115,3 +115,7 @@ QString FileLogger::getLogData() {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileLogger::sync() {
|
||||||
|
_persistThreadInstance->waitIdle();
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ public:
|
||||||
virtual void addMessage(const QString&) override;
|
virtual void addMessage(const QString&) override;
|
||||||
virtual QString getLogData() override;
|
virtual QString getLogData() override;
|
||||||
virtual void locateLog() override;
|
virtual void locateLog() override;
|
||||||
|
void sync();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void rollingLogFile(QString newFilename);
|
void rollingLogFile(QString newFilename);
|
||||||
|
|
|
@ -12,9 +12,10 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <QQueue>
|
#include <QtCore/QElapsedTimer>
|
||||||
#include <QMutex>
|
#include <QtCore/QMutex>
|
||||||
#include <QWaitCondition>
|
#include <QtCore/QQueue>
|
||||||
|
#include <QtCore/QWaitCondition>
|
||||||
|
|
||||||
#include "GenericThread.h"
|
#include "GenericThread.h"
|
||||||
#include "NumericalConstants.h"
|
#include "NumericalConstants.h"
|
||||||
|
@ -35,6 +36,25 @@ public:
|
||||||
_hasItems.wakeAll();
|
_hasItems.wakeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void waitIdle(uint32_t maxWaitMs = UINT32_MAX) {
|
||||||
|
QElapsedTimer timer;
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
// FIXME this will work as long as the thread doing the wait
|
||||||
|
// is the only thread which can add work to the queue.
|
||||||
|
// It would be better if instead we had a queue empty condition to wait on
|
||||||
|
// that would ensure that we get woken as soon as we're idle the very
|
||||||
|
// first time the queue was empty.
|
||||||
|
while (timer.elapsed() < maxWaitMs) {
|
||||||
|
lock();
|
||||||
|
if (!_items.size()) {
|
||||||
|
unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void queueItemInternal(const T& t) {
|
virtual void queueItemInternal(const T& t) {
|
||||||
_items.push_back(t);
|
_items.push_back(t);
|
||||||
|
@ -44,6 +64,7 @@ protected:
|
||||||
return MSECS_PER_SECOND;
|
return MSECS_PER_SECOND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual bool process() {
|
virtual bool process() {
|
||||||
lock();
|
lock();
|
||||||
if (!_items.size()) {
|
if (!_items.size()) {
|
||||||
|
|
Loading…
Reference in a new issue