mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-24 14:14:45 +02:00
Use backtrace_symbols() when printing stack traces on FreeBSD
Unfortunately, the symbol resolution of boost::stacktrace is broken on FreeBSD, therefore fall back to using backtrace_symbols() to print the stack trace saved by Boost. Additionally, -D_GNU_SOURCE is required on FreeBSD for the _Unwind_Backtrace function used by boost::stacktrace.
This commit is contained in:
parent
7d3885d05c
commit
b931194f59
@ -367,6 +367,15 @@ if(HAVE_LIBEXECINFO)
|
||||
set(HAVE_BACKTRACE_SYMBOLS TRUE)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
set(ICINGA2_STACKTRACE_USE_BACKTRACE_SYMBOLS TRUE)
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
endif()
|
||||
|
||||
if(ICINGA2_STACKTRACE_USE_BACKTRACE_SYMBOLS AND NOT HAVE_BACKTRACE_SYMBOLS)
|
||||
message(FATAL_ERROR "ICINGA2_STACKTRACE_USE_BACKTRACE_SYMBOLS is set but backtrace_symbols() was not found")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
exec_program(${CMAKE_CXX_COMPILER}
|
||||
ARGS -dumpversion
|
||||
|
@ -12,6 +12,7 @@
|
||||
#cmakedefine HAVE_SYSTEMD
|
||||
|
||||
#cmakedefine ICINGA2_UNITY_BUILD
|
||||
#cmakedefine ICINGA2_STACKTRACE_USE_BACKTRACE_SYMBOLS
|
||||
|
||||
#define ICINGA_CONFIGDIR "${ICINGA2_FULL_CONFIGDIR}"
|
||||
#define ICINGA_DATADIR "${ICINGA2_FULL_DATADIR}"
|
||||
|
@ -64,6 +64,7 @@ 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
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#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"
|
||||
@ -763,7 +764,7 @@ void Application::SigAbrtHandler(int)
|
||||
|
||||
DisplayInfoMessage(ofs);
|
||||
|
||||
ofs << "\nStacktrace:\n" << boost::stacktrace::stacktrace() << "\n";
|
||||
ofs << "\nStacktrace:\n" << StackTraceFormatter(boost::stacktrace::stacktrace()) << "\n";
|
||||
|
||||
DisplayBugMessage(ofs);
|
||||
|
||||
@ -954,7 +955,7 @@ LONG CALLBACK Application::SEHUnhandledExceptionFilter(PEXCEPTION_POINTERS exi)
|
||||
<< " Flags: " << exi->ExceptionRecord->ExceptionFlags << "\n";
|
||||
ofs.flags(savedflags);
|
||||
|
||||
ofs << "\nStacktrace:\n" << boost::stacktrace::stacktrace() << "\n";
|
||||
ofs << "\nStacktrace:\n" << StackTraceFormatter(boost::stacktrace::stacktrace()) << "\n";
|
||||
|
||||
DisplayBugMessage(ofs);
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#include "base/exception.hpp"
|
||||
#include "base/stacktrace.hpp"
|
||||
#include <boost/thread/tss.hpp>
|
||||
#include <utility>
|
||||
|
||||
@ -248,7 +249,7 @@ String icinga::DiagnosticInformation(const std::exception& ex, bool verbose, boo
|
||||
}
|
||||
|
||||
if (st && !st->empty()) {
|
||||
result << "\nStacktrace:\n" << *st;
|
||||
result << "\nStacktrace:\n" << StackTraceFormatter(*st);
|
||||
}
|
||||
}
|
||||
|
||||
|
36
lib/base/stacktrace.cpp
Normal file
36
lib/base/stacktrace.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
/* Icinga 2 | (c) 2020 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#include <base/i2-base.hpp>
|
||||
#include "base/stacktrace.hpp"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
|
||||
#ifdef HAVE_BACKTRACE_SYMBOLS
|
||||
# include <execinfo.h>
|
||||
#endif /* HAVE_BACKTRACE_SYMBOLS */
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
std::ostream &icinga::operator<<(std::ostream &os, const StackTraceFormatter &f)
|
||||
{
|
||||
const boost::stacktrace::stacktrace &stack = f.m_Stack;
|
||||
|
||||
#ifdef ICINGA2_STACKTRACE_USE_BACKTRACE_SYMBOLS
|
||||
std::vector<void *> addrs;
|
||||
addrs.reserve(stack.size());
|
||||
std::transform(stack.begin(), stack.end(), std::back_inserter(addrs), [](const boost::stacktrace::frame &f) {
|
||||
return const_cast<void *>(f.address());
|
||||
});
|
||||
|
||||
char **symbols = backtrace_symbols(addrs.data(), addrs.size());
|
||||
for (size_t i = 0; i < addrs.size(); i++) {
|
||||
os << std::setw(2) << i << "# " << symbols[i] << std::endl;
|
||||
}
|
||||
std::free(symbols);
|
||||
#else /* ICINGA2_STACKTRACE_USE_BACKTRACE_SYMBOLS */
|
||||
os << stack;
|
||||
#endif /* ICINGA2_STACKTRACE_USE_BACKTRACE_SYMBOLS */
|
||||
|
||||
return os;
|
||||
}
|
25
lib/base/stacktrace.hpp
Normal file
25
lib/base/stacktrace.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
/* Icinga 2 | (c) 2020 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#ifndef STACKTRACE_H
|
||||
#define STACKTRACE_H
|
||||
|
||||
#include <boost/stacktrace.hpp>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
class StackTraceFormatter {
|
||||
public:
|
||||
StackTraceFormatter(const boost::stacktrace::stacktrace &stack) : m_Stack(stack) {}
|
||||
|
||||
private:
|
||||
const boost::stacktrace::stacktrace &m_Stack;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, const StackTraceFormatter &f);
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const StackTraceFormatter &f);
|
||||
|
||||
}
|
||||
|
||||
#endif /* STACKTRACE_H */
|
Loading…
x
Reference in New Issue
Block a user