diff --git a/lib/base/CMakeLists.txt b/lib/base/CMakeLists.txt index 108ca27c1..ed8576b56 100644 --- a/lib/base/CMakeLists.txt +++ b/lib/base/CMakeLists.txt @@ -64,7 +64,6 @@ set(base_SOURCES shared-object.hpp singleton.hpp socket.cpp socket.hpp - stacktrace.cpp stacktrace.hpp statsfunction.hpp stdiostream.cpp stdiostream.hpp stream.cpp stream.hpp diff --git a/lib/base/application.cpp b/lib/base/application.cpp index 9d0d0475a..78af235cb 100644 --- a/lib/base/application.cpp +++ b/lib/base/application.cpp @@ -2,7 +2,6 @@ #include "base/application.hpp" #include "base/application-ti.cpp" -#include "base/stacktrace.hpp" #include "base/timer.hpp" #include "base/logger.hpp" #include "base/exception.hpp" @@ -761,9 +760,7 @@ void Application::SigAbrtHandler(int) DisplayInfoMessage(ofs); - StackTrace trace; - ofs << "Stacktrace:" << "\n"; - trace.Print(ofs, 1); + ofs << "\nStacktrace:\n" << boost::stacktrace::stacktrace() << "\n"; DisplayBugMessage(ofs); diff --git a/lib/base/exception.cpp b/lib/base/exception.cpp index cb505b04b..a080fdcba 100644 --- a/lib/base/exception.cpp +++ b/lib/base/exception.cpp @@ -14,7 +14,7 @@ using namespace icinga; -static boost::thread_specific_ptr l_LastExceptionStack; +static boost::thread_specific_ptr l_LastExceptionStack; static boost::thread_specific_ptr l_LastExceptionContext; #ifdef HAVE_CXXABI_H @@ -113,7 +113,7 @@ void __cxa_throw(void *obj, TYPEINFO_TYPE *pvtinfo, void (*dest)(void *)) if (!uex) { #endif /* NO_CAST_EXCEPTION */ - StackTrace stack; + boost::stacktrace::stacktrace stack; SetLastExceptionStack(stack); #ifndef NO_CAST_EXCEPTION @@ -134,14 +134,14 @@ void __cxa_throw(void *obj, TYPEINFO_TYPE *pvtinfo, void (*dest)(void *)) } #endif /* HAVE_CXXABI_H */ -StackTrace *icinga::GetLastExceptionStack() +boost::stacktrace::stacktrace *icinga::GetLastExceptionStack() { return l_LastExceptionStack.get(); } -void icinga::SetLastExceptionStack(const StackTrace& trace) +void icinga::SetLastExceptionStack(const boost::stacktrace::stacktrace& trace) { - l_LastExceptionStack.reset(new StackTrace(trace)); + l_LastExceptionStack.reset(new boost::stacktrace::stacktrace(trace)); } ContextTrace *icinga::GetLastExceptionContext() @@ -154,7 +154,7 @@ void icinga::SetLastExceptionContext(const ContextTrace& context) l_LastExceptionContext.reset(new ContextTrace(context)); } -String icinga::DiagnosticInformation(const std::exception& ex, bool verbose, StackTrace *stack, ContextTrace *context) +String icinga::DiagnosticInformation(const std::exception& ex, bool verbose, boost::stacktrace::stacktrace *stack, ContextTrace *context) { std::ostringstream result; @@ -216,7 +216,7 @@ String icinga::DiagnosticInformation(const std::exception& ex, bool verbose, Sta const auto *pex = dynamic_cast(&ex); if (!uex && !pex && verbose) { - const StackTrace *st = boost::get_error_info(ex); + const boost::stacktrace::stacktrace *st = boost::get_error_info(ex); if (st) { result << *st; @@ -251,8 +251,8 @@ String icinga::DiagnosticInformation(const std::exception& ex, bool verbose, Sta String icinga::DiagnosticInformation(const boost::exception_ptr& eptr, bool verbose) { - StackTrace *pt = GetLastExceptionStack(); - StackTrace stack; + boost::stacktrace::stacktrace *pt = GetLastExceptionStack(); + boost::stacktrace::stacktrace stack; ContextTrace *pc = GetLastExceptionContext(); ContextTrace context; diff --git a/lib/base/exception.hpp b/lib/base/exception.hpp index 7cc0ce7c7..1a4b71fcf 100644 --- a/lib/base/exception.hpp +++ b/lib/base/exception.hpp @@ -5,7 +5,6 @@ #include "base/i2-base.hpp" #include "base/string.hpp" -#include "base/stacktrace.hpp" #include "base/context.hpp" #include "base/debuginfo.hpp" #include "base/dictionary.hpp" @@ -15,6 +14,7 @@ #include #include #include +#include #ifdef _WIN32 # include @@ -76,15 +76,16 @@ private: Dictionary::Ptr m_DebugHint; }; -StackTrace *GetLastExceptionStack(); -void SetLastExceptionStack(const StackTrace& trace); +boost::stacktrace::stacktrace *GetLastExceptionStack(); +void SetLastExceptionStack(const boost::stacktrace::stacktrace& trace); ContextTrace *GetLastExceptionContext(); void SetLastExceptionContext(const ContextTrace& context); void RethrowUncaughtException(); -typedef boost::error_info StackTraceErrorInfo; +struct errinfo_stacktrace_; +typedef boost::error_info StackTraceErrorInfo; std::string to_string(const StackTraceErrorInfo&); @@ -92,7 +93,8 @@ typedef boost::error_info ContextTraceErrorInfo; std::string to_string(const ContextTraceErrorInfo& e); -String DiagnosticInformation(const std::exception& ex, bool verbose = true, StackTrace *stack = nullptr, ContextTrace *context = nullptr); +String DiagnosticInformation(const std::exception& ex, bool verbose = true, + boost::stacktrace::stacktrace *stack = nullptr, ContextTrace *context = nullptr); String DiagnosticInformation(const boost::exception_ptr& eptr, bool verbose = true); class posix_error : virtual public std::exception, virtual public boost::exception { diff --git a/lib/base/stacktrace.cpp b/lib/base/stacktrace.cpp deleted file mode 100644 index 81fdd3380..000000000 --- a/lib/base/stacktrace.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ - -#include "base/stacktrace.hpp" -#include "base/utility.hpp" -#include "base/initialize.hpp" - -#ifdef HAVE_BACKTRACE_SYMBOLS -# include -#endif /* HAVE_BACKTRACE_SYMBOLS */ - -using namespace icinga; - -#ifdef _MSC_VER -# pragma optimize("", off) -#endif /* _MSC_VER */ - -StackTrace::StackTrace() -{ -#ifdef HAVE_BACKTRACE_SYMBOLS - m_Count = backtrace(m_Frames, sizeof(m_Frames) / sizeof(m_Frames[0])); -#else /* HAVE_BACKTRACE_SYMBOLS */ -# ifdef _WIN32 - m_Count = CaptureStackBackTrace(0, sizeof(m_Frames) / sizeof(m_Frames), m_Frames, nullptr); -# else /* _WIN32 */ - m_Count = 0; -# endif /* _WIN32 */ -#endif /* HAVE_BACKTRACE_SYMBOLS */ -} - -#ifdef _MSC_VER -# pragma optimize("", on) -#endif /* _MSC_VER */ - -#ifdef _WIN32 -StackTrace::StackTrace(PEXCEPTION_POINTERS exi) -{ - STACKFRAME64 frame; - int architecture; - -#ifdef _WIN64 - architecture = IMAGE_FILE_MACHINE_AMD64; - - frame.AddrPC.Offset = exi->ContextRecord->Rip; - frame.AddrFrame.Offset = exi->ContextRecord->Rbp; - frame.AddrStack.Offset = exi->ContextRecord->Rsp; -#else /* _WIN64 */ - architecture = IMAGE_FILE_MACHINE_I386; - - frame.AddrPC.Offset = exi->ContextRecord->Eip; - frame.AddrFrame.Offset = exi->ContextRecord->Ebp; - frame.AddrStack.Offset = exi->ContextRecord->Esp; -#endif /* _WIN64 */ - - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrFrame.Mode = AddrModeFlat; - frame.AddrStack.Mode = AddrModeFlat; - - m_Count = 0; - - while (StackWalk64(architecture, GetCurrentProcess(), GetCurrentThread(), - &frame, exi->ContextRecord, nullptr, &SymFunctionTableAccess64, - &SymGetModuleBase64, nullptr) && m_Count < sizeof(m_Frames) / sizeof(m_Frames[0])) { - m_Frames[m_Count] = reinterpret_cast(frame.AddrPC.Offset); - m_Count++; - } -} -#endif /* _WIN32 */ - -#ifdef _WIN32 -INITIALIZE_ONCE([]() { - (void) SymSetOptions(SYMOPT_UNDNAME | SYMOPT_LOAD_LINES); - (void) SymInitialize(GetCurrentProcess(), nullptr, TRUE); -}); -#endif /* _WIN32 */ - -/** - * Prints a stacktrace to the specified stream. - * - * @param fp The stream. - * @param ignoreFrames The number of stackframes to ignore (in addition to - * the one this function is executing in). - * @returns true if the stacktrace was printed, false otherwise. - */ -void StackTrace::Print(std::ostream& fp, int ignoreFrames) const -{ - fp << std::endl; - -#ifndef _WIN32 -# ifdef HAVE_BACKTRACE_SYMBOLS - char **messages = backtrace_symbols(m_Frames, m_Count); - - for (int i = ignoreFrames + 1; i < m_Count && messages; ++i) { - String message = messages[i]; - - char *sym_begin = strchr(messages[i], '('); - - if (sym_begin) { - char *sym_end = strchr(sym_begin, '+'); - - if (sym_end) { - String sym = String(sym_begin + 1, sym_end); - String sym_demangled = Utility::DemangleSymbolName(sym); - - if (sym_demangled.IsEmpty()) - sym_demangled = ""; - - String path = String(messages[i], sym_begin); - - size_t slashp = path.RFind("/"); - - if (slashp != String::NPos) - path = path.SubStr(slashp + 1); - - message = path + ": " + sym_demangled + " (" + String(sym_end); - } - } - - fp << "\t(" << i - ignoreFrames - 1 << ") " << message << std::endl; - } - - std::free(messages); - - fp << std::endl; -# else /* HAVE_BACKTRACE_SYMBOLS */ - fp << "(not available)" << std::endl; -# endif /* HAVE_BACKTRACE_SYMBOLS */ -#else /* _WIN32 */ - for (int i = ignoreFrames + 1; i < m_Count; i++) { - fp << "\t(" << i - ignoreFrames - 1 << "): " << Utility::GetSymbolName(m_Frames[i]) << std::endl; - } -#endif /* _WIN32 */ -} - -std::ostream& icinga::operator<<(std::ostream& stream, const StackTrace& trace) -{ - trace.Print(stream, 1); - - return stream; -} diff --git a/lib/base/stacktrace.hpp b/lib/base/stacktrace.hpp deleted file mode 100644 index 1416d6558..000000000 --- a/lib/base/stacktrace.hpp +++ /dev/null @@ -1,38 +0,0 @@ -/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ - -#ifndef STACKTRACE_H -#define STACKTRACE_H - -#include "base/i2-base.hpp" -#include - -namespace icinga -{ - -/** - * A stacktrace. - * - * @ingroup base - */ -class StackTrace -{ -public: - StackTrace(); -#ifdef _WIN32 - explicit StackTrace(PEXCEPTION_POINTERS exi); -#endif /* _WIN32 */ - - void Print(std::ostream& fp, int ignoreFrames = 0) const; - - static void StaticInitialize(); - -private: - void *m_Frames[64]; - int m_Count; -}; - -std::ostream& operator<<(std::ostream& stream, const StackTrace& trace); - -} - -#endif /* UTILITY_H */ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3bcf04319..274456d1c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -16,7 +16,6 @@ set(base_test_SOURCES base-object-packer.cpp base-serialize.cpp base-shellescape.cpp - base-stacktrace.cpp base-stream.cpp base-string.cpp base-timer.cpp @@ -90,7 +89,6 @@ add_boost_test(base base_serialize/object base_shellescape/escape_basic base_shellescape/escape_quoted - base_stacktrace/stacktrace base_stream/readline_stdio base_string/construct base_string/equal diff --git a/test/base-stacktrace.cpp b/test/base-stacktrace.cpp deleted file mode 100644 index 349c2364a..000000000 --- a/test/base-stacktrace.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ - -#include "base/stacktrace.hpp" -#include - -using namespace icinga; - -BOOST_AUTO_TEST_SUITE(base_stacktrace) - -BOOST_AUTO_TEST_CASE(stacktrace) -{ - StackTrace st; - std::ostringstream obuf; - obuf << st; - BOOST_CHECK(obuf.str().size() > 0); -} - -BOOST_AUTO_TEST_SUITE_END()