summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-03-31 23:58:37 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-03-31 23:58:37 (GMT)
commitc912952fb5e8072770262c64932c1d8cf2027cf0 (patch)
treed21ae1340c96f9fe1105f9cdaa62d84342f58cd9 /apps
parentf64620e28a55dbddaeeefef2e7b8a6a433f21c82 (diff)
downloaduscxml-c912952fb5e8072770262c64932c1d8cf2027cf0.zip
uscxml-c912952fb5e8072770262c64932c1d8cf2027cf0.tar.gz
uscxml-c912952fb5e8072770262c64932c1d8cf2027cf0.tar.bz2
Various bug-fixes for W3C test conformance and stack traces with exceptions and segfaults
Diffstat (limited to 'apps')
-rw-r--r--apps/mmi-browser.cpp75
1 files changed, 75 insertions, 0 deletions
diff --git a/apps/mmi-browser.cpp b/apps/mmi-browser.cpp
index 56d7f02..6f997e7 100644
--- a/apps/mmi-browser.cpp
+++ b/apps/mmi-browser.cpp
@@ -6,6 +6,14 @@
#include <signal.h>
#endif
+#ifdef HAS_EXECINFO_H
+#include <execinfo.h>
+#endif
+
+#ifdef HAS_DLFCN_H
+#include <dlfcn.h>
+#endif
+
#ifdef _WIN32
#include "XGetopt.h"
#endif
@@ -30,6 +38,71 @@ class VerboseMonitor : public uscxml::InterpreterMonitor {
}
};
+
+#ifdef HAS_EXECINFO_H
+void printBacktrace(void** array, int size) {
+ char** messages = backtrace_symbols(array, size);
+ for (int i = 0; i < size && messages != NULL; ++i) {
+ std::cerr << "\t" << messages[i] << std::endl;
+ }
+ std::cerr << std::endl;
+ free(messages);
+}
+
+#ifdef HAS_DLFCN_H
+// see https://gist.github.com/nkuln/2020860
+typedef void (*cxa_throw_type)(void *, void *, void (*) (void *));
+cxa_throw_type orig_cxa_throw = 0;
+
+void load_orig_throw_code() {
+ orig_cxa_throw = (cxa_throw_type) dlsym(RTLD_NEXT, "__cxa_throw");
+}
+
+extern "C"
+void __cxa_throw (void *thrown_exception, void *pvtinfo, void (*dest)(void *)) {
+ std::cerr << __FUNCTION__ << " will throw exception from " << std::endl;
+ if (orig_cxa_throw == 0)
+ load_orig_throw_code();
+
+ void *array[50];
+ size_t size = backtrace(array, 50);
+ printBacktrace(array, size);
+ orig_cxa_throw(thrown_exception, pvtinfo, dest);
+}
+#endif
+#endif
+
+
+// see http://stackoverflow.com/questions/2443135/how-do-i-find-where-an-exception-was-thrown-in-c
+void customTerminate() {
+ static bool tried_throw = false;
+ try {
+ // try once to re-throw currently active exception
+ if (!tried_throw) {
+ throw;
+ tried_throw = true;
+ } else {
+ tried_throw = false;
+ };
+ }
+ catch (const std::exception &e) {
+ std::cerr << __FUNCTION__ << " caught unhandled exception. what(): "
+ << e.what() << std::endl;
+ }
+ catch (...) {
+ std::cerr << __FUNCTION__ << " caught unknown/unhandled exception."
+ << std::endl;
+ }
+
+#ifdef HAS_EXECINFO_H
+ void * array[50];
+ int size = backtrace(array, 50);
+
+ printBacktrace(array, size);
+#endif
+ abort();
+}
+
void printUsageAndExit() {
printf("mmi-browser version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n");
printf("Usage\n");
@@ -48,6 +121,8 @@ void printUsageAndExit() {
int main(int argc, char** argv) {
using namespace uscxml;
+ std::set_terminate(customTerminate);
+
#ifdef HAS_SIGNAL_H
signal(SIGPIPE, SIG_IGN);
#endif