]> granicus.if.org Git - icinga2/commitdiff
Make exception messages more verbose.
authorGunnar Beutner <gunnar.beutner@netways.de>
Thu, 27 Sep 2012 07:38:28 +0000 (09:38 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Thu, 27 Sep 2012 07:38:28 +0000 (09:38 +0200)
configure.ac
icinga-app/Makefile.am
icinga-app/icinga.cpp
lib/base/application.cpp
lib/base/utility.cpp
lib/base/utility.h

index be72913acdf4adb33476ce3e99c6bfa6dd5a3811..2f49a9f0a64c8b520a4947b28a8c6125331e4be8 100644 (file)
@@ -64,6 +64,7 @@ AC_CHECK_LIB(m, floor)
 AC_CHECK_LIB(socket, getsockname)
 AC_CHECK_LIB(ws2_32, getsockname)
 AC_CHECK_LIB(shlwapi, PathRemoveFileSpecA)
+AC_CHECK_FUNCS([backtrace_symbols])
 
 AC_CONFIG_FILES([
 Makefile
index fb27b3287b6808e8ee618db5c77e43be6aaa22ad..8c7a64dfa5925d95721803b8f02cc05673aab3ce 100644 (file)
@@ -21,7 +21,8 @@ icinga2_CPPFLAGS = \
        -DICINGA_LIBDIR="\"$(pkglibdir)\""
 
 icinga2_LDFLAGS = \
-       $(BOOST_LDFLAGS)
+       $(BOOST_LDFLAGS) \
+       -export-dynamic
 
 icinga2_LDADD = \
        $(LIBLTDL) \
index f59777501c03c5d93290bd8f75a920b958009a7a..af2ca239fe9687c4b5e97c5df08f8953c88b17bc 100644 (file)
@@ -18,6 +18,7 @@
  ******************************************************************************/
 
 #include <i2-icinga.h>
+#include <execinfo.h>
 
 #ifndef _WIN32
 #      include "icinga-version.h"
 
 using namespace icinga;
 
+/**
+ * Handler for unhandled exceptions.
+ *
+ */
+static void exception_handler(void)
+{
+       static bool rethrow = true;
+
+       try {
+               rethrow = false;
+               throw;
+       } catch (const std::exception& ex) {
+               std::cerr << std::endl;
+               std::cerr << "Unhandled exception of type "
+                         << Utility::GetTypeName(typeid(ex))
+                         << std::endl;
+               std::cerr << "Diagnostic Information: "
+                         << ex.what()
+                         << std::endl;
+       }
+
+#ifdef HAVE_BACKTRACE_SYMBOLS
+       void *frames[50];
+       int framecount = backtrace(frames, sizeof(frames) / sizeof(frames[0]));
+
+       char **messages = backtrace_symbols(frames, framecount);
+
+       std::cerr << std::endl << "Stacktrace:" << std::endl;
+
+       for (int i = 0; i < framecount && messages != NULL; ++i) {
+               String message = messages[i];
+
+               char *sym_begin = strchr(messages[i], '(');
+
+               if (sym_begin != NULL) {
+                       char *sym_end = strchr(sym_begin, '+');
+
+                       if (sym_end != NULL) {
+                               String sym = String(sym_begin + 1, sym_end);
+                               String sym_demangled = Utility::DemangleSymbolName(sym);
+
+                               if (sym_demangled.IsEmpty())
+                                       sym_demangled = "<unknown function>";
+
+                               message = String(messages[i], sym_begin) + ": " + sym_demangled + " (" + String(sym_end);
+                       }
+               }
+
+               std::cerr << "\t(" << i << ") " << message << std::endl;
+       }
+
+       free(messages);
+
+       std::cerr << std::endl;
+#endif /* HAVE_BACKTRACE_SYMBOLS */
+
+       abort();
+}
+
 /**
  * Entry point for the Icinga application.
  *
@@ -37,6 +97,8 @@ using namespace icinga;
  */
 int main(int argc, char **argv)
 {
+       std::set_terminate(exception_handler);
+
 #ifndef _WIN32
        LTDL_SET_PRELOADED_SYMBOLS();
 #endif /* _WIN32 */
index 5a423b804e4a046c37800cb6e80e69d6a2bd087f..5071be06f8bf3c0ad040c8ed8f92d68f22c84e40 100644 (file)
@@ -338,19 +338,7 @@ int Application::Run(int argc, char **argv)
 
        DynamicObject::BeginTx();
 
-       if (IsDebugging()) {
-               result = Main(m_Arguments);
-       } else {
-               try {
-                       result = Main(m_Arguments);
-               } catch (const exception& ex) {
-                       Logger::Write(LogCritical, "base", "---");
-                       Logger::Write(LogCritical, "base", "Exception: " + Utility::GetTypeName(typeid(ex)));
-                       Logger::Write(LogCritical, "base", "Message: " + String(ex.what()));
-
-                       result = EXIT_FAILURE;
-               }
-       }
+       result = Main(m_Arguments);
 
        DynamicObject::FinishTx();
        DynamicObject::DeactivateObjects();
index e388739b654361ec75048ef5cd46656478052460..21aff8b36bd6d7b749b8ccdb85a3845a73b1d255 100644 (file)
@@ -25,28 +25,38 @@ using namespace icinga;
 bool I2_EXPORT Utility::m_SSLInitialized = false;
 
 /**
- * Returns a human-readable type name of a type_info object.
+ * Demangles a symbol name.
  *
- * @param ti A type_info object.
- * @returns The type name of the object.
+ * @param sym The symbol name.
+ * @returns A human-readable version of the symbol name.
  */
-String Utility::GetTypeName(const type_info& ti)
+String Utility::DemangleSymbolName(const String& sym)
 {
-       String klass = ti.name();
+       String result = sym;
 
 #ifdef HAVE_GCC_ABI_DEMANGLE
        int status;
-       char *realname = abi::__cxa_demangle(klass.CStr(), 0, 0, &status);
+       char *realname = abi::__cxa_demangle(sym.CStr(), 0, 0, &status);
 
        if (realname != NULL) {
-               klass = String(realname);
+               result = String(realname);
                free(realname);
        }
 #endif /* HAVE_GCC_ABI_DEMANGLE */
 
-       return klass;
+       return result;
 }
 
+/**
+ * Returns a human-readable type name of a type_info object.
+ *
+ * @param ti A type_info object.
+ * @returns The type name of the object.
+ */
+String Utility::GetTypeName(const type_info& ti)
+{
+       return DemangleSymbolName(ti.name());
+}
 
 /**
  * Detaches from the controlling terminal.
index b1f5d00eac8dbee6b363eb703abd7908e4e79972..50c97ce3fe5a2412785ed8f4857bf95f8f0a3b93 100644 (file)
@@ -31,6 +31,7 @@ namespace icinga
 class I2_BASE_API Utility
 {
 public:
+       static String DemangleSymbolName(const String& sym);
        static String GetTypeName(const type_info& ti);
 
        static void Daemonize(void);