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(socket, getsockname)
|
||||||
AC_CHECK_LIB(ws2_32, getsockname)
|
AC_CHECK_LIB(ws2_32, getsockname)
|
||||||
AC_CHECK_LIB(shlwapi, PathRemoveFileSpecA)
|
AC_CHECK_LIB(shlwapi, PathRemoveFileSpecA)
|
||||||
|
AC_CHECK_FUNCS([backtrace_symbols])
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
|
|
|
@ -21,7 +21,8 @@ icinga2_CPPFLAGS = \
|
||||||
-DICINGA_LIBDIR="\"$(pkglibdir)\""
|
-DICINGA_LIBDIR="\"$(pkglibdir)\""
|
||||||
|
|
||||||
icinga2_LDFLAGS = \
|
icinga2_LDFLAGS = \
|
||||||
$(BOOST_LDFLAGS)
|
$(BOOST_LDFLAGS) \
|
||||||
|
-export-dynamic
|
||||||
|
|
||||||
icinga2_LDADD = \
|
icinga2_LDADD = \
|
||||||
$(LIBLTDL) \
|
$(LIBLTDL) \
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include <i2-icinga.h>
|
#include <i2-icinga.h>
|
||||||
|
#include <execinfo.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# include "icinga-version.h"
|
# include "icinga-version.h"
|
||||||
|
@ -28,6 +29,65 @@
|
||||||
|
|
||||||
using namespace icinga;
|
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.
|
* Entry point for the Icinga application.
|
||||||
*
|
*
|
||||||
|
@ -37,6 +97,8 @@ using namespace icinga;
|
||||||
*/
|
*/
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
std::set_terminate(exception_handler);
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
LTDL_SET_PRELOADED_SYMBOLS();
|
LTDL_SET_PRELOADED_SYMBOLS();
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
|
@ -338,19 +338,7 @@ int Application::Run(int argc, char **argv)
|
||||||
|
|
||||||
DynamicObject::BeginTx();
|
DynamicObject::BeginTx();
|
||||||
|
|
||||||
if (IsDebugging()) {
|
|
||||||
result = Main(m_Arguments);
|
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::FinishTx();
|
||||||
DynamicObject::DeactivateObjects();
|
DynamicObject::DeactivateObjects();
|
||||||
|
|
|
@ -24,6 +24,29 @@ using namespace icinga;
|
||||||
|
|
||||||
bool I2_EXPORT Utility::m_SSLInitialized = false;
|
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.
|
* 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 Utility::GetTypeName(const type_info& ti)
|
||||||
{
|
{
|
||||||
String klass = ti.name();
|
return DemangleSymbolName(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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detaches from the controlling terminal.
|
* Detaches from the controlling terminal.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace icinga
|
||||||
class I2_BASE_API Utility
|
class I2_BASE_API Utility
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static String DemangleSymbolName(const String& sym);
|
||||||
static String GetTypeName(const type_info& ti);
|
static String GetTypeName(const type_info& ti);
|
||||||
|
|
||||||
static void Daemonize(void);
|
static void Daemonize(void);
|
||||||
|
|
Loading…
Reference in New Issue