diff --git a/applications/gui/src/main.cpp b/applications/gui/src/main.cpp
index 2677d67358af7a7bb9906e2d1ee93b99a372df5b..4bc4e197b1f7a4124024f1c0deaf43d48fecc1ed 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 821c2eee75fdd21e6fa4ff7a7911686c01a50787..7c5794d1ba8d882dbdfd98620994a4aad2275d39 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 de21aea545c08dbb74f85add523a292db4d036c7..d86f9017a45df07de1961ad468712911694161c1 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 0000000000000000000000000000000000000000..0284f6b73882e5f2d475dddadcd307fc42c3eb84
--- /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