Fix another exception issue with FreeBSD.

Refs #6008
This commit is contained in:
Gunnar Beutner 2014-04-14 03:02:33 +02:00
parent 25b598300f
commit 8c771d51e4
7 changed files with 40 additions and 1 deletions

View File

@ -106,6 +106,11 @@ check_function_exists(backtrace_symbols HAVE_BACKTRACE_SYMBOLS)
check_function_exists(pipe2 HAVE_PIPE2) check_function_exists(pipe2 HAVE_PIPE2)
check_library_exists(dl dladdr "dlfcn.h" HAVE_DLADDR) check_library_exists(dl dladdr "dlfcn.h" HAVE_DLADDR)
check_library_exists(crypto BIO_f_zlib "" HAVE_BIOZLIB) check_library_exists(crypto BIO_f_zlib "" HAVE_BIOZLIB)
check_library_exists(execinfo backtrace_symbols "" HAVE_LIBEXECINFO)
if(HAVE_LIBEXECINFO)
set(HAVE_BACKTRACE_SYMBOLS TRUE)
endif()
include(GNUInstallDirs) include(GNUInstallDirs)
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h ESCAPE_QUOTES) configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h ESCAPE_QUOTES)

View File

@ -27,6 +27,7 @@ parentheses):
on Debian) on Debian)
* GNU bison (bison) * GNU bison (bison)
* GNU flex (flex) >= 2.5.35 * GNU flex (flex) >= 2.5.35
* recommended: libexecinfo on FreeBSD
* optional: Doxygen (doxygen) * optional: Doxygen (doxygen)
* optional: MySQL (mysql-devel on RHEL, libmysqlclient-dev on Debian) * optional: MySQL (mysql-devel on RHEL, libmysqlclient-dev on Debian)
* optional: Python (python-devel on RHEL, python-dev on Debian) * optional: Python (python-devel on RHEL, python-dev on Debian)

View File

@ -6,6 +6,7 @@
#cmakedefine HAVE_PIPE2 #cmakedefine HAVE_PIPE2
#cmakedefine HAVE_VFORK #cmakedefine HAVE_VFORK
#cmakedefine HAVE_DLADDR #cmakedefine HAVE_DLADDR
#cmakedefine HAVE_LIBEXECINFO
#define ICINGA_PREFIX "${CMAKE_INSTALL_PREFIX}" #define ICINGA_PREFIX "${CMAKE_INSTALL_PREFIX}"
#define ICINGA_SYSCONFDIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}" #define ICINGA_SYSCONFDIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}"

View File

@ -38,6 +38,10 @@ add_library(base SHARED
target_link_libraries(base ${CMAKE_DL_LIBS} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} cJSON mmatch) target_link_libraries(base ${CMAKE_DL_LIBS} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} cJSON mmatch)
if(HAVE_LIBEXECINFO)
target_link_libraries(base execinfo)
endif()
include_directories(${icinga2_SOURCE_DIR}/third-party/cJSON) include_directories(${icinga2_SOURCE_DIR}/third-party/cJSON)
link_directories(${icinga2_BINARY_DIR}/third-party/cJSON) link_directories(${icinga2_BINARY_DIR}/third-party/cJSON)

View File

@ -452,7 +452,7 @@ void Application::ExceptionHandler(void)
DisplayVersionMessage(); DisplayVersionMessage();
try { try {
throw; RethrowUncaughtException();
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
std::cerr << std::endl std::cerr << std::endl
<< DiagnosticInformation(ex) << DiagnosticInformation(ex)

View File

@ -25,12 +25,38 @@ static boost::thread_specific_ptr<StackTrace> l_LastExceptionStack;
static boost::thread_specific_ptr<ContextTrace> l_LastExceptionContext; static boost::thread_specific_ptr<ContextTrace> l_LastExceptionContext;
#ifndef _WIN32 #ifndef _WIN32
#ifndef __GLIBCXX__
static boost::thread_specific_ptr<void *> l_LastExceptionObj;
static boost::thread_specific_ptr<void *> l_LastExceptionPvtInfo;
typedef void (*DestCallback)(void *);
static boost::thread_specific_ptr<DestCallback> l_LastExceptionDest;
extern "C" void __cxa_throw(void *obj, void *pvtinfo, void (*dest)(void *));
extern "C" void __cxa_rethrow_primary_exception(void* thrown_object);
#endif /* __GLIBCXX__ */
void icinga::RethrowUncaughtException(void)
{
#ifdef __GLIBCXX__
throw;
#else /* __GLIBCXX__ */
__cxa_throw(*l_LastExceptionObj.get(), *l_LastExceptionPvtInfo.get(), *l_LastExceptionDest.get());
#endif /* __GLIBCXX__ */
}
extern "C" extern "C"
void __cxa_throw(void *obj, void *pvtinfo, void (*dest)(void *)) void __cxa_throw(void *obj, void *pvtinfo, void (*dest)(void *))
{ {
typedef void (*cxa_throw_fn)(void *, void *, void (*) (void *)) __attribute__((noreturn)); typedef void (*cxa_throw_fn)(void *, void *, void (*) (void *)) __attribute__((noreturn));
static cxa_throw_fn real_cxa_throw; static cxa_throw_fn real_cxa_throw;
#ifndef __GLIBCXX__
l_LastExceptionObj.reset(new void *(obj));
l_LastExceptionPvtInfo.reset(new void *(pvtinfo));
l_LastExceptionDest.reset(new DestCallback(dest));
#endif /* __GLIBCXX__ */
if (real_cxa_throw == 0) if (real_cxa_throw == 0)
real_cxa_throw = (cxa_throw_fn)dlsym(RTLD_NEXT, "__cxa_throw"); real_cxa_throw = (cxa_throw_fn)dlsym(RTLD_NEXT, "__cxa_throw");

View File

@ -47,6 +47,8 @@ I2_BASE_API void SetLastExceptionStack(const StackTrace& trace);
I2_BASE_API ContextTrace *GetLastExceptionContext(void); I2_BASE_API ContextTrace *GetLastExceptionContext(void);
I2_BASE_API void SetLastExceptionContext(const ContextTrace& context); I2_BASE_API void SetLastExceptionContext(const ContextTrace& context);
I2_BASE_API void RethrowUncaughtException(void);
typedef boost::error_info<StackTrace, StackTrace> StackTraceErrorInfo; typedef boost::error_info<StackTrace, StackTrace> StackTraceErrorInfo;
typedef boost::error_info<ContextTrace, ContextTrace> ContextTraceErrorInfo; typedef boost::error_info<ContextTrace, ContextTrace> ContextTraceErrorInfo;