mirror of https://github.com/Icinga/icinga2.git
Make exception messages more verbose.
This commit is contained in:
parent
74a3bca0f6
commit
c5479057f7
|
@ -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
|
||||
|
|
|
@ -21,7 +21,8 @@ icinga2_CPPFLAGS = \
|
|||
-DICINGA_LIBDIR="\"$(pkglibdir)\""
|
||||
|
||||
icinga2_LDFLAGS = \
|
||||
$(BOOST_LDFLAGS)
|
||||
$(BOOST_LDFLAGS) \
|
||||
-export-dynamic
|
||||
|
||||
icinga2_LDADD = \
|
||||
$(LIBLTDL) \
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
******************************************************************************/
|
||||
|
||||
#include <i2-icinga.h>
|
||||
#include <execinfo.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include "icinga-version.h"
|
||||
|
@ -28,6 +29,65 @@
|
|||
|
||||
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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
DynamicObject::FinishTx();
|
||||
DynamicObject::DeactivateObjects();
|
||||
|
|
|
@ -24,6 +24,29 @@ using namespace icinga;
|
|||
|
||||
bool I2_EXPORT Utility::m_SSLInitialized = false;
|
||||
|
||||
/**
|
||||
* Demangles a symbol name.
|
||||
*
|
||||
* @param sym The symbol name.
|
||||
* @returns A human-readable version of the symbol name.
|
||||
*/
|
||||
String Utility::DemangleSymbolName(const String& sym)
|
||||
{
|
||||
String result = sym;
|
||||
|
||||
#ifdef HAVE_GCC_ABI_DEMANGLE
|
||||
int status;
|
||||
char *realname = abi::__cxa_demangle(sym.CStr(), 0, 0, &status);
|
||||
|
||||
if (realname != NULL) {
|
||||
result = String(realname);
|
||||
free(realname);
|
||||
}
|
||||
#endif /* HAVE_GCC_ABI_DEMANGLE */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable type name of a type_info object.
|
||||
*
|
||||
|
@ -32,22 +55,9 @@ bool I2_EXPORT Utility::m_SSLInitialized = false;
|
|||
*/
|
||||
String Utility::GetTypeName(const type_info& ti)
|
||||
{
|
||||
String klass = ti.name();
|
||||
|
||||
#ifdef HAVE_GCC_ABI_DEMANGLE
|
||||
int status;
|
||||
char *realname = abi::__cxa_demangle(klass.CStr(), 0, 0, &status);
|
||||
|
||||
if (realname != NULL) {
|
||||
klass = String(realname);
|
||||
free(realname);
|
||||
}
|
||||
#endif /* HAVE_GCC_ABI_DEMANGLE */
|
||||
|
||||
return klass;
|
||||
return DemangleSymbolName(ti.name());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detaches from the controlling terminal.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue