Revert catching c++ exceptions (triggered on situations when it should been silent), avoid crash of uninitialized GL and fix lockup when mainwindow doesn't exist
This commit is contained in:
parent
4f3d3b573f
commit
565d51ad99
5 changed files with 66 additions and 49 deletions
|
@ -3,15 +3,7 @@
|
||||||
#include "texception.h"
|
#include "texception.h"
|
||||||
#include "tconvert.h"
|
#include "tconvert.h"
|
||||||
|
|
||||||
static TString s_lastMsg;
|
TException::TException(const std::string &msg) { m_msg = ::to_wstring(msg); }
|
||||||
|
|
||||||
TException::TException(const std::string &msg) {
|
|
||||||
m_msg = ::to_wstring(msg);
|
|
||||||
s_lastMsg = getMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
TString TException::getLastMessage() { return s_lastMsg; }
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ostream& operator<<(ostream &out, const TException &e)
|
ostream& operator<<(ostream &out, const TException &e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,7 +23,6 @@ public:
|
||||||
explicit TException(const std::wstring &msg) : m_msg(msg) {}
|
explicit TException(const std::wstring &msg) : m_msg(msg) {}
|
||||||
virtual ~TException() {}
|
virtual ~TException() {}
|
||||||
virtual TString getMessage() const { return m_msg; }
|
virtual TString getMessage() const { return m_msg; }
|
||||||
static TString getLastMessage();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// DVAPI ostream& operator<<(ostream &out, const TException &e);
|
// DVAPI ostream& operator<<(ostream &out, const TException &e);
|
||||||
|
|
|
@ -41,6 +41,9 @@
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
|
static QWidget *s_parentWindow = NULL;
|
||||||
|
static bool s_reportProjInfo = false;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
static const char *filenameOnly(const char *path) {
|
static const char *filenameOnly(const char *path) {
|
||||||
|
@ -195,9 +198,9 @@ static void printBacktrace(std::string &out) {
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
LONG WINAPI exceptionHandler(PEXCEPTION_POINTERS info) {
|
LONG WINAPI exceptionHandler(PEXCEPTION_POINTERS info) {
|
||||||
const char *reason = "Unknown";
|
static volatile bool handling = false;
|
||||||
int accessType;
|
|
||||||
|
|
||||||
|
const char *reason = "Unknown";
|
||||||
switch (info->ExceptionRecord->ExceptionCode) {
|
switch (info->ExceptionRecord->ExceptionCode) {
|
||||||
case EXCEPTION_ACCESS_VIOLATION:
|
case EXCEPTION_ACCESS_VIOLATION:
|
||||||
reason = "EXCEPTION_ACCESS_VIOLATION";
|
reason = "EXCEPTION_ACCESS_VIOLATION";
|
||||||
|
@ -250,14 +253,16 @@ LONG WINAPI exceptionHandler(PEXCEPTION_POINTERS info) {
|
||||||
case EXCEPTION_STACK_OVERFLOW:
|
case EXCEPTION_STACK_OVERFLOW:
|
||||||
reason = "EXCEPTION_STACK_OVERFLOW";
|
reason = "EXCEPTION_STACK_OVERFLOW";
|
||||||
break;
|
break;
|
||||||
case 0xE06D7363: // Magic number... oof
|
|
||||||
reason = "C++ Exception";
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avoid new exceptions inside the crash handler
|
||||||
|
if (handling) return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
|
||||||
|
handling = true;
|
||||||
if (CrashHandler::trigger(reason, true)) _Exit(1);
|
if (CrashHandler::trigger(reason, true)) _Exit(1);
|
||||||
|
handling = false;
|
||||||
|
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
|
@ -348,8 +353,9 @@ static void printBacktrace(std::string &out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void signalHandler(int sig) {
|
void signalHandler(int sig) {
|
||||||
QString reason = "Unknown";
|
static volatile bool handling = false;
|
||||||
|
|
||||||
|
const char *reason = "Unknown";
|
||||||
switch (sig) {
|
switch (sig) {
|
||||||
case SIGABRT:
|
case SIGABRT:
|
||||||
reason = "(SIGABRT) Usually caused by an abort() or assert()";
|
reason = "(SIGABRT) Usually caused by an abort() or assert()";
|
||||||
|
@ -371,7 +377,12 @@ void signalHandler(int sig) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avoid new signals inside the crash handler
|
||||||
|
if (handling) return;
|
||||||
|
|
||||||
|
handling = true;
|
||||||
if (CrashHandler::trigger(reason, true)) _Exit(1);
|
if (CrashHandler::trigger(reason, true)) _Exit(1);
|
||||||
|
handling = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -389,12 +400,15 @@ static void printSysInfo(std::string &out) {
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
static void printGPUInfo(std::string &out) {
|
static void printGPUInfo(std::string &out) {
|
||||||
std::string gpuVendorName = (const char *)glGetString(GL_VENDOR);
|
const char *gpuVendorName = (const char *)glGetString(GL_VENDOR);
|
||||||
std::string gpuModelName = (const char *)glGetString(GL_RENDERER);
|
const char *gpuModelName = (const char *)glGetString(GL_RENDERER);
|
||||||
std::string gpuVersion = (const char *)glGetString(GL_VERSION);
|
const char *gpuVersion = (const char *)glGetString(GL_VERSION);
|
||||||
out.append("GPU Vendor: " + gpuVendorName + "\n");
|
if (gpuVendorName)
|
||||||
out.append("GPU Model: " + gpuModelName + "\n");
|
out.append("GPU Vendor: " + std::string(gpuVendorName) + "\n");
|
||||||
out.append("GPU Version: " + gpuVersion + "\n");
|
if (gpuModelName)
|
||||||
|
out.append("GPU Model: " + std::string(gpuModelName) + "\n");
|
||||||
|
if (gpuVersion)
|
||||||
|
out.append("GPU Version: " + std::string(gpuVersion) + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -506,6 +520,18 @@ void CrashHandler::install() {
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CrashHandler::reportProjectInfo(bool enableReport) {
|
||||||
|
s_reportProjInfo = enableReport;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CrashHandler::attachParentWindow(QWidget *parent) {
|
||||||
|
s_parentWindow = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CrashHandler::trigger(const QString reason, bool showDialog) {
|
bool CrashHandler::trigger(const QString reason, bool showDialog) {
|
||||||
char fileName[128];
|
char fileName[128];
|
||||||
char dumpName[128];
|
char dumpName[128];
|
||||||
|
@ -527,17 +553,11 @@ bool CrashHandler::trigger(const QString reason, bool showDialog) {
|
||||||
|
|
||||||
// Generate report
|
// Generate report
|
||||||
try {
|
try {
|
||||||
TString exception = TException::getLastMessage();
|
|
||||||
|
|
||||||
out.append(TEnv::getApplicationFullName() + " (Build " + __DATE__ ")\n");
|
out.append(TEnv::getApplicationFullName() + " (Build " + __DATE__ ")\n");
|
||||||
out.append("\nReport Date: ");
|
out.append("\nReport Date: ");
|
||||||
out.append(dateName);
|
out.append(dateName);
|
||||||
out.append("\nCrash Reason: ");
|
out.append("\nCrash Reason: ");
|
||||||
out.append(reason.toStdString());
|
out.append(reason.toStdString());
|
||||||
if (!exception.empty()) {
|
|
||||||
out.append("\nException: ");
|
|
||||||
out.append(::to_string(exception));
|
|
||||||
}
|
|
||||||
out.append("\n\n");
|
out.append("\n\n");
|
||||||
printSysInfo(out);
|
printSysInfo(out);
|
||||||
out.append("\n");
|
out.append("\n");
|
||||||
|
@ -555,28 +575,31 @@ bool CrashHandler::trigger(const QString reason, bool showDialog) {
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
TProjectManager *pm = TProjectManager::instance();
|
if (s_reportProjInfo) {
|
||||||
|
TProjectManager *pm = TProjectManager::instance();
|
||||||
|
TApp *app = TApp::instance();
|
||||||
|
|
||||||
TProjectP currentProject = pm->getCurrentProject();
|
TProjectP currentProject = pm->getCurrentProject();
|
||||||
TFilePath projectPath = currentProject->getProjectPath();
|
TFilePath projectPath = currentProject->getProjectPath();
|
||||||
|
|
||||||
ToonzScene *currentScene = TApp::instance()->getCurrentScene()->getScene();
|
ToonzScene *currentScene = app->getCurrentScene()->getScene();
|
||||||
std::wstring sceneName = currentScene->getSceneName();
|
std::wstring sceneName = currentScene->getSceneName();
|
||||||
|
|
||||||
out.append("\nApplication Dir: ");
|
out.append("\nApplication Dir: ");
|
||||||
out.append(QCoreApplication::applicationDirPath().toStdString());
|
out.append(QCoreApplication::applicationDirPath().toStdString());
|
||||||
out.append("\nStuff Dir: ");
|
out.append("\nStuff Dir: ");
|
||||||
out.append(TEnv::getStuffDir().getQString().toStdString());
|
out.append(TEnv::getStuffDir().getQString().toStdString());
|
||||||
out.append("\n");
|
out.append("\n");
|
||||||
out.append("\nProject Name: ");
|
out.append("\nProject Name: ");
|
||||||
out.append(currentProject->getName().getQString().toStdString());
|
out.append(currentProject->getName().getQString().toStdString());
|
||||||
out.append("\nScene Name: ");
|
out.append("\nScene Name: ");
|
||||||
out.append(QString::fromStdWString(sceneName).toStdString());
|
out.append(QString::fromStdWString(sceneName).toStdString());
|
||||||
out.append("\nProject Path: ");
|
out.append("\nProject Path: ");
|
||||||
out.append(projectPath.getQString().toStdString());
|
out.append(projectPath.getQString().toStdString());
|
||||||
out.append("\nScene Path: ");
|
out.append("\nScene Path: ");
|
||||||
out.append(currentScene->getScenePath().getQString().toStdString());
|
out.append(currentScene->getScenePath().getQString().toStdString());
|
||||||
out.append("\n");
|
out.append("\n");
|
||||||
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
#ifdef HAS_MODULES
|
#ifdef HAS_MODULES
|
||||||
|
@ -605,8 +628,7 @@ bool CrashHandler::trigger(const QString reason, bool showDialog) {
|
||||||
|
|
||||||
if (showDialog) {
|
if (showDialog) {
|
||||||
// Show crash handler dialog
|
// Show crash handler dialog
|
||||||
CrashHandler crashdialog(TApp::instance()->getMainWindow(), fpCrsh,
|
CrashHandler crashdialog(s_parentWindow, fpCrsh, QString::fromStdString(out));
|
||||||
QString::fromStdString(out));
|
|
||||||
return crashdialog.exec() != QDialog::Rejected;
|
return crashdialog.exec() != QDialog::Rejected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ public:
|
||||||
void reject();
|
void reject();
|
||||||
|
|
||||||
static void install();
|
static void install();
|
||||||
|
static void reportProjectInfo(bool enableReport);
|
||||||
|
static void attachParentWindow(QWidget *parent);
|
||||||
static bool trigger(const QString reason, bool showDialog);
|
static bool trigger(const QString reason, bool showDialog);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -672,6 +672,8 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
/*-- Layoutファイル名をMainWindowのctorに渡す --*/
|
/*-- Layoutファイル名をMainWindowのctorに渡す --*/
|
||||||
MainWindow w(argumentLayoutFileName);
|
MainWindow w(argumentLayoutFileName);
|
||||||
|
CrashHandler::attachParentWindow(&w);
|
||||||
|
CrashHandler::reportProjectInfo(true);
|
||||||
|
|
||||||
TFilePath fp = ToonzFolder::getModuleFile("mainwindow.ini");
|
TFilePath fp = ToonzFolder::getModuleFile("mainwindow.ini");
|
||||||
QSettings settings(toQString(fp), QSettings::IniFormat);
|
QSettings settings(toQString(fp), QSettings::IniFormat);
|
||||||
|
|
Loading…
Reference in a new issue