mirror of
https://github.com/Icinga/icinga2.git
synced 2025-05-31 03:40:18 +02:00
Implement automated stacktraces for exceptions.
This commit is contained in:
parent
e2416b5b54
commit
cada2abeb3
@ -88,7 +88,7 @@ String CompatComponent::GetCommandPath(void) const
|
|||||||
|
|
||||||
Value commandPath = config->Get("command_path");
|
Value commandPath = config->Get("command_path");
|
||||||
if (commandPath.IsEmpty())
|
if (commandPath.IsEmpty())
|
||||||
return Application::GetLocalStateDir() + "/run/icinga/icinga2.cmd";
|
return Application::GetLocalStateDir() + "/run/icinga2/icinga2.cmd";
|
||||||
else
|
else
|
||||||
return commandPath;
|
return commandPath;
|
||||||
}
|
}
|
||||||
|
@ -83,12 +83,6 @@ else
|
|||||||
fi
|
fi
|
||||||
AC_MSG_RESULT($enable_debug)
|
AC_MSG_RESULT($enable_debug)
|
||||||
|
|
||||||
AX_C___ATTRIBUTE__
|
|
||||||
if test "$ax_cv___attribute__" = "yes" && test "x$enable_debug" = "xno"; then
|
|
||||||
CFLAGS="$CFLAGS -fvisibility=hidden"
|
|
||||||
CXXFLAGS="$CXXFLAGS -fvisibility=hidden"
|
|
||||||
fi
|
|
||||||
|
|
||||||
AX_PYTHON_DEFAULT
|
AX_PYTHON_DEFAULT
|
||||||
AX_PYTHON_ENABLE
|
AX_PYTHON_ENABLE
|
||||||
AX_PYTHON_VERSION_ENSURE([2.5])
|
AX_PYTHON_VERSION_ENSURE([2.5])
|
||||||
|
@ -353,16 +353,24 @@ void Application::ExceptionHandler(void)
|
|||||||
sigaction(SIGABRT, &sa, NULL);
|
sigaction(SIGABRT, &sa, NULL);
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
bool has_trace = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
throw;
|
throw;
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
std::cerr << std::endl
|
std::cerr << std::endl
|
||||||
<< diagnostic_information(ex)
|
<< diagnostic_information(ex)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
has_trace = (boost::get_error_info<StackTraceErrorInfo>(ex) != NULL);
|
||||||
|
} catch (...) {
|
||||||
|
std::cerr << "Exception of unknown type." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
StackTrace trace;
|
if (!has_trace) {
|
||||||
trace.Print(std::cerr, 1);
|
StackTrace trace;
|
||||||
|
trace.Print(std::cerr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
DisplayBugMessage();
|
DisplayBugMessage();
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
|
StackTrace *Exception::m_StackTrace = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the error code for the exception.
|
* Retrieves the error code for the exception.
|
||||||
*
|
*
|
||||||
@ -125,3 +127,47 @@ String OpenSSLException::FormatErrorCode(int code)
|
|||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
extern "C"
|
||||||
|
void __cxa_throw(void *obj, void *pvtinfo, void (*dest)(void *))
|
||||||
|
{
|
||||||
|
typedef void (*cxa_throw_fn)(void *, void *, void (*) (void *)) __attribute__((noreturn));
|
||||||
|
static cxa_throw_fn real_cxa_throw;
|
||||||
|
|
||||||
|
if (real_cxa_throw == 0)
|
||||||
|
real_cxa_throw = (cxa_throw_fn)dlsym(RTLD_NEXT, "__cxa_throw");
|
||||||
|
|
||||||
|
void *thrown_ptr = obj;
|
||||||
|
const type_info *tinfo = static_cast<type_info *>(pvtinfo);
|
||||||
|
const type_info *boost_exc = &typeid(boost::exception);
|
||||||
|
|
||||||
|
/* Check if the exception is a pointer type. */
|
||||||
|
if (tinfo->__is_pointer_p())
|
||||||
|
thrown_ptr = *(void **)thrown_ptr;
|
||||||
|
|
||||||
|
/* Check if thrown_ptr inherits from boost::exception. */
|
||||||
|
if (boost_exc->__do_catch(tinfo, &thrown_ptr, 1)) {
|
||||||
|
boost::exception *ex = (boost::exception *)thrown_ptr;
|
||||||
|
|
||||||
|
StackTrace trace;
|
||||||
|
*ex << StackTraceErrorInfo(trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
real_cxa_throw(obj, pvtinfo, dest);
|
||||||
|
}
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
StackTrace *Exception::GetLastStackTrace(void)
|
||||||
|
{
|
||||||
|
return m_StackTrace;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exception::SetLastStackTrace(const StackTrace& trace)
|
||||||
|
{
|
||||||
|
if (m_StackTrace)
|
||||||
|
delete m_StackTrace;
|
||||||
|
|
||||||
|
m_StackTrace = new StackTrace(trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,9 @@ public:
|
|||||||
|
|
||||||
virtual const char *what(void) const throw();
|
virtual const char *what(void) const throw();
|
||||||
|
|
||||||
|
static StackTrace *GetLastStackTrace(void);
|
||||||
|
static void SetLastStackTrace(const StackTrace& trace);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetCode(int code);
|
void SetCode(int code);
|
||||||
void SetMessage(String message);
|
void SetMessage(String message);
|
||||||
@ -61,8 +64,12 @@ protected:
|
|||||||
private:
|
private:
|
||||||
String m_Message;
|
String m_Message;
|
||||||
int m_Code;
|
int m_Code;
|
||||||
|
|
||||||
|
static StackTrace *m_StackTrace;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef boost::error_info<StackTrace, StackTrace> StackTraceErrorInfo;
|
||||||
|
|
||||||
#define DEFINE_EXCEPTION_CLASS(klass) \
|
#define DEFINE_EXCEPTION_CLASS(klass) \
|
||||||
class klass : public Exception \
|
class klass : public Exception \
|
||||||
{ \
|
{ \
|
||||||
|
@ -102,7 +102,7 @@ void StackTrace::Initialize(void)
|
|||||||
* the one this function is executing in).
|
* the one this function is executing in).
|
||||||
* @returns true if the stacktrace was printed, false otherwise.
|
* @returns true if the stacktrace was printed, false otherwise.
|
||||||
*/
|
*/
|
||||||
void StackTrace::Print(ostream& fp, int ignoreFrames)
|
void StackTrace::Print(ostream& fp, int ignoreFrames) const
|
||||||
{
|
{
|
||||||
fp << std::endl << "Stacktrace:" << std::endl;
|
fp << std::endl << "Stacktrace:" << std::endl;
|
||||||
|
|
||||||
@ -170,3 +170,9 @@ void StackTrace::Print(ostream& fp, int ignoreFrames)
|
|||||||
}
|
}
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ostream& icinga::operator<<(ostream& stream, const StackTrace& trace)
|
||||||
|
{
|
||||||
|
trace.Print(stream, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
StackTrace(PEXCEPTION_POINTERS exi);
|
StackTrace(PEXCEPTION_POINTERS exi);
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
void Print(ostream& fp, int ignoreFrames = 0);
|
void Print(ostream& fp, int ignoreFrames = 0) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void *m_Frames[64];
|
void *m_Frames[64];
|
||||||
@ -47,6 +47,8 @@ private:
|
|||||||
static void Initialize(void);
|
static void Initialize(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
I2_BASE_API ostream& operator<<(ostream& stream, const StackTrace& trace);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* UTILITY_H */
|
#endif /* UTILITY_H */
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
#include <ltdl.h>
|
#include <ltdl.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
typedef int SOCKET;
|
typedef int SOCKET;
|
||||||
#define INVALID_SOCKET (-1)
|
#define INVALID_SOCKET (-1)
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
# ===========================================================================
|
|
||||||
# http://www.gnu.org/software/autoconf-archive/ax_c___attribute__.html
|
|
||||||
# ===========================================================================
|
|
||||||
#
|
|
||||||
# SYNOPSIS
|
|
||||||
#
|
|
||||||
# AX_C___ATTRIBUTE__
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# Provides a test for the compiler support of __attribute__ extensions.
|
|
||||||
# Defines HAVE___ATTRIBUTE__ if it is found.
|
|
||||||
#
|
|
||||||
# LICENSE
|
|
||||||
#
|
|
||||||
# Copyright (c) 2008 Stepan Kasal <skasal@redhat.com>
|
|
||||||
# Copyright (c) 2008 Christian Haggstrom
|
|
||||||
# Copyright (c) 2008 Ryan McCabe <ryan@numb.org>
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify it
|
|
||||||
# under the terms of the GNU General Public License as published by the
|
|
||||||
# Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
# option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
||||||
# Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along
|
|
||||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
|
||||||
# gives unlimited permission to copy, distribute and modify the configure
|
|
||||||
# scripts that are the output of Autoconf when processing the Macro. You
|
|
||||||
# need not follow the terms of the GNU General Public License when using
|
|
||||||
# or distributing such scripts, even though portions of the text of the
|
|
||||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
|
||||||
# all other use of the material that constitutes the Autoconf Macro.
|
|
||||||
#
|
|
||||||
# This special exception to the GPL applies to versions of the Autoconf
|
|
||||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
|
||||||
# modified version of the Autoconf Macro, you may extend this special
|
|
||||||
# exception to the GPL to apply to your modified version as well.
|
|
||||||
|
|
||||||
#serial 8
|
|
||||||
|
|
||||||
AC_DEFUN([AX_C___ATTRIBUTE__], [
|
|
||||||
AC_CACHE_CHECK([for __attribute__], [ax_cv___attribute__],
|
|
||||||
[AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM(
|
|
||||||
[[#include <stdlib.h>
|
|
||||||
static void foo(void) __attribute__ ((unused));
|
|
||||||
static void
|
|
||||||
foo(void) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
]], [])],
|
|
||||||
[ax_cv___attribute__=yes],
|
|
||||||
[ax_cv___attribute__=no]
|
|
||||||
)
|
|
||||||
])
|
|
||||||
if test "$ax_cv___attribute__" = "yes"; then
|
|
||||||
AC_DEFINE([HAVE___ATTRIBUTE__], 1, [define if your compiler has __attribute__])
|
|
||||||
fi
|
|
||||||
])
|
|
Loading…
x
Reference in New Issue
Block a user