diff --git a/toonz/sources/common/tcore/texception.cpp b/toonz/sources/common/tcore/texception.cpp index fe1b468..c5cab15 100644 --- a/toonz/sources/common/tcore/texception.cpp +++ b/toonz/sources/common/tcore/texception.cpp @@ -3,15 +3,7 @@ #include "texception.h" #include "tconvert.h" -static TString s_lastMsg; - -TException::TException(const std::string &msg) { - m_msg = ::to_wstring(msg); - s_lastMsg = getMessage(); -} - -TString TException::getLastMessage() { return s_lastMsg; } - +TException::TException(const std::string &msg) { m_msg = ::to_wstring(msg); } /* ostream& operator<<(ostream &out, const TException &e) { diff --git a/toonz/sources/include/texception.h b/toonz/sources/include/texception.h index ec79033..30b1ed1 100644 --- a/toonz/sources/include/texception.h +++ b/toonz/sources/include/texception.h @@ -23,7 +23,6 @@ public: explicit TException(const std::wstring &msg) : m_msg(msg) {} virtual ~TException() {} virtual TString getMessage() const { return m_msg; } - static TString getLastMessage(); }; // DVAPI ostream& operator<<(ostream &out, const TException &e); diff --git a/toonz/sources/toonz/crashhandler.cpp b/toonz/sources/toonz/crashhandler.cpp index c56f03b..2dc0082 100644 --- a/toonz/sources/toonz/crashhandler.cpp +++ b/toonz/sources/toonz/crashhandler.cpp @@ -41,6 +41,9 @@ #include #include +static QWidget *s_parentWindow = NULL; +static bool s_reportProjInfo = false; + //----------------------------------------------------------------------------- static const char *filenameOnly(const char *path) { @@ -195,9 +198,9 @@ static void printBacktrace(std::string &out) { //----------------------------------------------------------------------------- LONG WINAPI exceptionHandler(PEXCEPTION_POINTERS info) { - const char *reason = "Unknown"; - int accessType; + static volatile bool handling = false; + const char *reason = "Unknown"; switch (info->ExceptionRecord->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: reason = "EXCEPTION_ACCESS_VIOLATION"; @@ -250,14 +253,16 @@ LONG WINAPI exceptionHandler(PEXCEPTION_POINTERS info) { case EXCEPTION_STACK_OVERFLOW: reason = "EXCEPTION_STACK_OVERFLOW"; break; - case 0xE06D7363: // Magic number... oof - reason = "C++ Exception"; - break; default: 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); + handling = false; return EXCEPTION_CONTINUE_SEARCH; } @@ -348,8 +353,9 @@ static void printBacktrace(std::string &out) { } void signalHandler(int sig) { - QString reason = "Unknown"; + static volatile bool handling = false; + const char *reason = "Unknown"; switch (sig) { case SIGABRT: reason = "(SIGABRT) Usually caused by an abort() or assert()"; @@ -371,7 +377,12 @@ void signalHandler(int sig) { break; } + // Avoid new signals inside the crash handler + if (handling) return; + + handling = true; if (CrashHandler::trigger(reason, true)) _Exit(1); + handling = false; } #endif @@ -389,12 +400,15 @@ static void printSysInfo(std::string &out) { //----------------------------------------------------------------------------- static void printGPUInfo(std::string &out) { - std::string gpuVendorName = (const char *)glGetString(GL_VENDOR); - std::string gpuModelName = (const char *)glGetString(GL_RENDERER); - std::string gpuVersion = (const char *)glGetString(GL_VERSION); - out.append("GPU Vendor: " + gpuVendorName + "\n"); - out.append("GPU Model: " + gpuModelName + "\n"); - out.append("GPU Version: " + gpuVersion + "\n"); + const char *gpuVendorName = (const char *)glGetString(GL_VENDOR); + const char *gpuModelName = (const char *)glGetString(GL_RENDERER); + const char *gpuVersion = (const char *)glGetString(GL_VERSION); + if (gpuVendorName) + out.append("GPU Vendor: " + std::string(gpuVendorName) + "\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) { char fileName[128]; char dumpName[128]; @@ -527,17 +553,11 @@ bool CrashHandler::trigger(const QString reason, bool showDialog) { // Generate report try { - TString exception = TException::getLastMessage(); - out.append(TEnv::getApplicationFullName() + " (Build " + __DATE__ ")\n"); out.append("\nReport Date: "); out.append(dateName); out.append("\nCrash Reason: "); out.append(reason.toStdString()); - if (!exception.empty()) { - out.append("\nException: "); - out.append(::to_string(exception)); - } out.append("\n\n"); printSysInfo(out); out.append("\n"); @@ -555,28 +575,31 @@ bool CrashHandler::trigger(const QString reason, bool showDialog) { } catch (...) { } try { - TProjectManager *pm = TProjectManager::instance(); + if (s_reportProjInfo) { + TProjectManager *pm = TProjectManager::instance(); + TApp *app = TApp::instance(); - TProjectP currentProject = pm->getCurrentProject(); - TFilePath projectPath = currentProject->getProjectPath(); + TProjectP currentProject = pm->getCurrentProject(); + TFilePath projectPath = currentProject->getProjectPath(); - ToonzScene *currentScene = TApp::instance()->getCurrentScene()->getScene(); - std::wstring sceneName = currentScene->getSceneName(); + ToonzScene *currentScene = app->getCurrentScene()->getScene(); + std::wstring sceneName = currentScene->getSceneName(); - out.append("\nApplication Dir: "); - out.append(QCoreApplication::applicationDirPath().toStdString()); - out.append("\nStuff Dir: "); - out.append(TEnv::getStuffDir().getQString().toStdString()); - out.append("\n"); - out.append("\nProject Name: "); - out.append(currentProject->getName().getQString().toStdString()); - out.append("\nScene Name: "); - out.append(QString::fromStdWString(sceneName).toStdString()); - out.append("\nProject Path: "); - out.append(projectPath.getQString().toStdString()); - out.append("\nScene Path: "); - out.append(currentScene->getScenePath().getQString().toStdString()); - out.append("\n"); + out.append("\nApplication Dir: "); + out.append(QCoreApplication::applicationDirPath().toStdString()); + out.append("\nStuff Dir: "); + out.append(TEnv::getStuffDir().getQString().toStdString()); + out.append("\n"); + out.append("\nProject Name: "); + out.append(currentProject->getName().getQString().toStdString()); + out.append("\nScene Name: "); + out.append(QString::fromStdWString(sceneName).toStdString()); + out.append("\nProject Path: "); + out.append(projectPath.getQString().toStdString()); + out.append("\nScene Path: "); + out.append(currentScene->getScenePath().getQString().toStdString()); + out.append("\n"); + } } catch (...) { } #ifdef HAS_MODULES @@ -605,8 +628,7 @@ bool CrashHandler::trigger(const QString reason, bool showDialog) { if (showDialog) { // Show crash handler dialog - CrashHandler crashdialog(TApp::instance()->getMainWindow(), fpCrsh, - QString::fromStdString(out)); + CrashHandler crashdialog(s_parentWindow, fpCrsh, QString::fromStdString(out)); return crashdialog.exec() != QDialog::Rejected; } diff --git a/toonz/sources/toonz/crashhandler.h b/toonz/sources/toonz/crashhandler.h index 8398e53..3e94ab3 100644 --- a/toonz/sources/toonz/crashhandler.h +++ b/toonz/sources/toonz/crashhandler.h @@ -20,6 +20,8 @@ public: void reject(); static void install(); + static void reportProjectInfo(bool enableReport); + static void attachParentWindow(QWidget *parent); static bool trigger(const QString reason, bool showDialog); public slots: diff --git a/toonz/sources/toonz/main.cpp b/toonz/sources/toonz/main.cpp index 2d24b9e..1e941d3 100644 --- a/toonz/sources/toonz/main.cpp +++ b/toonz/sources/toonz/main.cpp @@ -661,6 +661,8 @@ int main(int argc, char *argv[]) { /*-- Layoutファイル名をMainWindowのctorに渡す --*/ MainWindow w(argumentLayoutFileName); + CrashHandler::attachParentWindow(&w); + CrashHandler::reportProjectInfo(true); if (isRunScript) { // load script