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 <QTextEdit>
 #include <QPushButton>
 
+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