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;
}
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])
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();
using namespace icinga;
+StackTrace *Exception::m_StackTrace = NULL;
+
/**
* Retrieves the error code for the exception.
*
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);
+}
+
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);
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 \
{ \
* 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;
}
#endif /* _WIN32 */
}
+
+ostream& icinga::operator<<(ostream& stream, const StackTrace& trace)
+{
+ trace.Print(stream, 1);
+}
+
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];
static void Initialize(void);
};
+I2_BASE_API ostream& operator<<(ostream& stream, const StackTrace& trace);
+
}
#endif /* UTILITY_H */
#include <poll.h>
#include <glob.h>
#include <ltdl.h>
+#include <dlfcn.h>
typedef int SOCKET;
#define INVALID_SOCKET (-1)
+++ /dev/null
-# ===========================================================================
-# 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
-])