mirror of
https://github.com/Icinga/icinga2.git
synced 2025-05-28 18:30: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");
|
||||
if (commandPath.IsEmpty())
|
||||
return Application::GetLocalStateDir() + "/run/icinga/icinga2.cmd";
|
||||
return Application::GetLocalStateDir() + "/run/icinga2/icinga2.cmd";
|
||||
else
|
||||
return commandPath;
|
||||
}
|
||||
|
@ -83,12 +83,6 @@ else
|
||||
fi
|
||||
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_ENABLE
|
||||
AX_PYTHON_VERSION_ENSURE([2.5])
|
||||
|
@ -353,16 +353,24 @@ void Application::ExceptionHandler(void)
|
||||
sigaction(SIGABRT, &sa, NULL);
|
||||
#endif /* _WIN32 */
|
||||
|
||||
bool has_trace = false;
|
||||
|
||||
try {
|
||||
throw;
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << std::endl
|
||||
<< diagnostic_information(ex)
|
||||
<< std::endl;
|
||||
|
||||
has_trace = (boost::get_error_info<StackTraceErrorInfo>(ex) != NULL);
|
||||
} catch (...) {
|
||||
std::cerr << "Exception of unknown type." << std::endl;
|
||||
}
|
||||
|
||||
StackTrace trace;
|
||||
trace.Print(std::cerr, 1);
|
||||
if (!has_trace) {
|
||||
StackTrace trace;
|
||||
trace.Print(std::cerr, 1);
|
||||
}
|
||||
|
||||
DisplayBugMessage();
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
StackTrace *Exception::m_StackTrace = NULL;
|
||||
|
||||
/**
|
||||
* Retrieves the error code for the exception.
|
||||
*
|
||||
@ -125,3 +127,47 @@ String OpenSSLException::FormatErrorCode(int code)
|
||||
|
||||
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();
|
||||
|
||||
static StackTrace *GetLastStackTrace(void);
|
||||
static void SetLastStackTrace(const StackTrace& trace);
|
||||
|
||||
protected:
|
||||
void SetCode(int code);
|
||||
void SetMessage(String message);
|
||||
@ -61,8 +64,12 @@ protected:
|
||||
private:
|
||||
String m_Message;
|
||||
int m_Code;
|
||||
|
||||
static StackTrace *m_StackTrace;
|
||||
};
|
||||
|
||||
typedef boost::error_info<StackTrace, StackTrace> StackTraceErrorInfo;
|
||||
|
||||
#define DEFINE_EXCEPTION_CLASS(klass) \
|
||||
class klass : public Exception \
|
||||
{ \
|
||||
|
@ -102,7 +102,7 @@ void StackTrace::Initialize(void)
|
||||
* the one this function is executing in).
|
||||
* @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;
|
||||
|
||||
@ -170,3 +170,9 @@ void StackTrace::Print(ostream& fp, int ignoreFrames)
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
ostream& icinga::operator<<(ostream& stream, const StackTrace& trace)
|
||||
{
|
||||
trace.Print(stream, 1);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
StackTrace(PEXCEPTION_POINTERS exi);
|
||||
#endif /* _WIN32 */
|
||||
|
||||
void Print(ostream& fp, int ignoreFrames = 0);
|
||||
void Print(ostream& fp, int ignoreFrames = 0) const;
|
||||
|
||||
private:
|
||||
void *m_Frames[64];
|
||||
@ -47,6 +47,8 @@ private:
|
||||
static void Initialize(void);
|
||||
};
|
||||
|
||||
I2_BASE_API ostream& operator<<(ostream& stream, const StackTrace& trace);
|
||||
|
||||
}
|
||||
|
||||
#endif /* UTILITY_H */
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <poll.h>
|
||||
#include <glob.h>
|
||||
#include <ltdl.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
typedef int SOCKET;
|
||||
#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