From b5f188cd0185f5ebc606f587c7b8db14c92dc032 Mon Sep 17 00:00:00 2001
From: Nicolas Pope <nwpope@utu.fi>
Date: Thu, 27 Feb 2020 08:50:37 +0200
Subject: [PATCH] Attempt to dump stack trace on uncaught exceptions

---
 applications/gui/src/main.cpp                 |  5 ++-
 components/common/cpp/CMakeLists.txt          |  1 +
 .../common/cpp/include/ftl/exception.hpp      |  9 ++++--
 components/common/cpp/src/exception.cpp       | 32 +++++++++++++++++++
 4 files changed, 44 insertions(+), 3 deletions(-)
 create mode 100644 components/common/cpp/src/exception.cpp

diff --git a/applications/gui/src/main.cpp b/applications/gui/src/main.cpp
index 2677d6735..4bc4e197b 100644
--- a/applications/gui/src/main.cpp
+++ b/applications/gui/src/main.cpp
@@ -89,12 +89,15 @@ int main(int argc, char **argv) {
 		}
 
 		nanogui::shutdown();
+	} catch (const ftl::exception &e) {
+		LOG(ERROR) << "Fatal error: " << e.what();
+		LOG(ERROR) << e.trace();
 	} catch (const std::runtime_error &e) {
 		std::string error_msg = std::string("Caught a fatal error: ") + std::string(e.what());
 		#if defined(_WIN32)
 			MessageBoxA(nullptr, error_msg.c_str(), NULL, MB_ICONERROR | MB_OK);
 		#else
-			std::cerr << error_msg << std::endl;
+			LOG(ERROR) << error_msg;
 		#endif
 		return -1;
 	}
diff --git a/components/common/cpp/CMakeLists.txt b/components/common/cpp/CMakeLists.txt
index 821c2eee7..7c5794d1b 100644
--- a/components/common/cpp/CMakeLists.txt
+++ b/components/common/cpp/CMakeLists.txt
@@ -11,6 +11,7 @@ set(COMMONSRC
 	src/ctpl_stl.cpp
 	src/timer.cpp
 	src/profiler.cpp
+	src/exception.cpp
 )
 
 check_function_exists(uriParseSingleUriA HAVE_URIPARSESINGLE)
diff --git a/components/common/cpp/include/ftl/exception.hpp b/components/common/cpp/include/ftl/exception.hpp
index de21aea54..d86f9017a 100644
--- a/components/common/cpp/include/ftl/exception.hpp
+++ b/components/common/cpp/include/ftl/exception.hpp
@@ -35,15 +35,20 @@ private:
 class exception : public std::exception
 {
 	public:
-	explicit exception(const char *msg) : msg_(msg) {}
-	explicit exception(const Formatter &msg) : msg_(msg.str()) {}
+	explicit exception(const char *msg);
+	explicit exception(const Formatter &msg);
 
 	const char * what () const throw () {
     	return msg_.c_str();
     }
 
+    const char * trace () const throw () {
+        return trace_.c_str();
+    }
+
 	private:
 	std::string msg_;
+    std::string trace_;
 };
 }
 
diff --git a/components/common/cpp/src/exception.cpp b/components/common/cpp/src/exception.cpp
new file mode 100644
index 000000000..0284f6b73
--- /dev/null
+++ b/components/common/cpp/src/exception.cpp
@@ -0,0 +1,32 @@
+#include <ftl/exception.hpp>
+
+#ifndef WIN32
+#include <execinfo.h>
+#endif
+
+using ftl::exception;
+using std::string;
+
+exception::exception(const char *msg) : msg_(msg) {
+    #ifndef WIN32
+    void *trace[16];
+    char **messages = (char **)NULL;
+    int trace_size = 0;
+
+    trace_size = backtrace(trace, 16);
+
+    trace_ = "[bt] Trace:\n";
+
+    messages = backtrace_symbols(trace, trace_size);
+
+    /* skip first stack frame (points here) */
+    for (int i=1; i<trace_size; ++i) {
+        printf("[bt] #%d %s\n", i, messages[i]);
+        trace_ += string("[bt] #") + std::to_string(i) + string(" ") + messages[i];
+    }
+    #endif
+}
+
+exception::exception(const Formatter &msg) : msg_(msg.str()) {
+
+}
\ No newline at end of file
-- 
GitLab