aboutsummaryrefslogtreecommitdiffstats
path: root/gui
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-07-20 13:22:47 +0100
committergatecat <gatecat@ds0.me>2021-07-20 15:01:34 +0100
commit41eecd7ce2e2200e5f76da1974a86c6f35831d1b (patch)
tree24240ecb3313c17c931b9ffdfd70e80411e4b2e2 /gui
parentf3be638ea9536511d329d3e1ad726e847916f122 (diff)
downloadnextpnr-41eecd7ce2e2200e5f76da1974a86c6f35831d1b.tar.gz
nextpnr-41eecd7ce2e2200e5f76da1974a86c6f35831d1b.tar.bz2
nextpnr-41eecd7ce2e2200e5f76da1974a86c6f35831d1b.zip
gui: Improve Fatal Error message
Signed-off-by: gatecat <gatecat@ds0.me>
Diffstat (limited to 'gui')
-rw-r--r--gui/application.cc68
1 files changed, 57 insertions, 11 deletions
diff --git a/gui/application.cc b/gui/application.cc
index 3f6d538b..d3260684 100644
--- a/gui/application.cc
+++ b/gui/application.cc
@@ -27,6 +27,10 @@
#include <exception>
#include "log.h"
+#ifdef __linux__
+#include <execinfo.h>
+#endif
+
NEXTPNR_NAMESPACE_BEGIN
#ifdef _WIN32
@@ -39,6 +43,53 @@ BOOL WINAPI WinHandler(DWORD dwCtrlType)
}
#endif
+namespace {
+#ifdef __linux__
+std::string get_backtrace_str()
+{
+ static const size_t MAX_BT_SIZE = 1024;
+ std::array<void *, MAX_BT_SIZE> bt_data;
+ int bt_len = backtrace(bt_data.data(), MAX_BT_SIZE);
+ char **bt_symbols = backtrace_symbols(bt_data.data(), bt_len);
+ if (bt_symbols == nullptr)
+ return "";
+ std::ostringstream ss;
+ ss << "Backtrace: " << std::endl;
+ for (int i = 0; i < bt_len; i++)
+ ss << " " << bt_symbols[i] << std::endl;
+ free(bt_symbols);
+ return ss.str();
+}
+#else
+std::string get_backtrace_str() { return ""; }
+#endif
+
+void do_error()
+{
+ std::string bt = get_backtrace_str();
+
+ std::exception_ptr eptr = std::current_exception();
+ std::string err_msg = "Unknown Exception Type";
+
+ try {
+ if (eptr) {
+ std::rethrow_exception(eptr);
+ }
+ } catch (const std::exception &e) {
+ err_msg = e.what();
+ } catch (...) {
+ }
+
+ QString msg;
+ QTextStream out(&msg);
+ out << "Internal Error: " << err_msg.c_str() << "\n";
+ out << bt.c_str();
+ QMessageBox::critical(0, "Error", msg);
+ std::abort();
+}
+
+} // namespace
+
Application::Application(int &argc, char **argv, bool noantialiasing) : QApplication(argc, argv)
{
QSurfaceFormat fmt;
@@ -64,23 +115,18 @@ Application::Application(int &argc, char **argv, bool noantialiasing) : QApplica
#ifdef _WIN32
SetConsoleCtrlHandler((PHANDLER_ROUTINE)WinHandler, TRUE);
#endif
+
+ std::set_terminate(do_error);
}
bool Application::notify(QObject *receiver, QEvent *event)
{
- bool retVal = true;
try {
- retVal = QApplication::notify(receiver, event);
- } catch (const assertion_failure &ex) {
- QString msg;
- QTextStream out(&msg);
- out << ex.filename.c_str() << " at " << ex.line << "\n";
- out << ex.msg.c_str();
- QMessageBox::critical(0, "Error", msg);
- } catch (...) {
- QMessageBox::critical(0, "Error", "Fatal error !!!");
+ return QApplication::notify(receiver, event);
+ } catch (log_execution_error_exception) {
+ QMessageBox::critical(0, "Error", "Pass failed, see log for details!");
+ return true;
}
- return retVal;
}
NEXTPNR_NAMESPACE_END