Minor improvements and refactoring

This commit is contained in:
Antony Polukhin
2016-10-11 23:22:38 +03:00
parent 73206b9c64
commit e1c1a4910b
16 changed files with 401 additions and 249 deletions

View File

@@ -18,6 +18,8 @@
#include <string>
/// @cond
// Link or header only
#if !defined(BOOST_STACKTRACE_LINK) && defined(BOOST_STACKTRACE_DYN_LINK)
# define BOOST_STACKTRACE_LINK
#endif
@@ -26,6 +28,28 @@
# define BOOST_STACKTRACE_DYN_LINK
#endif
// Backend autodetection
#if !defined(BOOST_STACKTRACE_USE_NOOP) && !defined(BOOST_STACKTRACE_USE_WINDBG) && !defined(BOOST_STACKTRACE_USE_LIBUNWIND) \
&& !defined(BOOST_STACKTRACE_USE_BACKTRACE) &&!defined(BOOST_STACKTRACE_USE_HEADER)
#if defined(__has_include) && (!defined(__GNUC__) || __GNUC__ > 4 || BOOST_CLANG)
# if __has_include(<libunwind.h>)
# define BOOST_STACKTRACE_USE_LIBUNWIND
# elif __has_include(<execinfo.h>)
# define BOOST_STACKTRACE_USE_BACKTRACE
# elif __has_include("DbgHelp.h")
# define BOOST_STACKTRACE_USE_WINDBG
# endif
#else
# if defined(BOOST_WINDOWS)
# define BOOST_STACKTRACE_USE_WINDBG
# else
# define BOOST_STACKTRACE_USE_BACKTRACE
# endif
#endif
#endif
#ifdef BOOST_STACKTRACE_LINK
# if defined(BOOST_STACKTRACE_DYN_LINK)
# ifdef BOOST_STACKTRACE_INTERNAL_BUILD_LIBS
@@ -38,14 +62,29 @@
# endif
#else
# define BOOST_STACKTRACE_FUNCTION inline
# if defined(BOOST_STACKTRACE_USE_NOOP)
# include <boost/stacktrace/detail/backtrace_holder_noop.hpp>
# elif defined(BOOST_STACKTRACE_USE_WINDBG)
# include <boost/stacktrace/detail/backtrace_holder_windows.hpp>
# elif defined(BOOST_STACKTRACE_USE_LIBUNWIND)
# include <boost/stacktrace/detail/backtrace_holder_libunwind.hpp>
# elif defined(BOOST_STACKTRACE_USE_BACKTRACE)
# include <boost/stacktrace/detail/backtrace_holder_linux.hpp>
# else
# error No suitable backtrace backend found
# endif
#endif
/// @endcond
namespace boost { namespace stacktrace {
class stacktrace {
#ifdef BOOST_STACKTRACE_LINK
BOOST_STATIC_CONSTEXPR std::size_t max_implementation_size = sizeof(void*) * 110u;
boost::aligned_storage<max_implementation_size>::type impl_;
#else
boost::stacktrace::detail::backtrace_holder impl_;
#endif
public:
/// @brief Stores the current function call sequence inside the class.

View File

@@ -0,0 +1,83 @@
// Copyright Antony Polukhin, 2016.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_STACKTRACE_DETAIL_BACKTRACE_HOLDER_LIBUNWIND_HPP
#define BOOST_STACKTRACE_DETAIL_BACKTRACE_HOLDER_LIBUNWIND_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <boost/core/demangle.hpp>
#include <cstring>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/make_shared.hpp>
#define UNW_LOCAL_ONLY
#include <libunwind.h>
namespace boost { namespace stacktrace { namespace detail {
struct backtrace_holder {
std::size_t frames_count;
boost::shared_ptr<std::string[]> frames;
BOOST_FORCEINLINE backtrace_holder() BOOST_NOEXCEPT
: frames_count(0)
{}
inline std::size_t size() const BOOST_NOEXCEPT {
return frames_count;
}
inline std::string get_frame(std::size_t frame) const {
if (frame < frames_count) {
return frames[frame];
} else {
return std::string();
}
}
static inline std::string get_frame_impl(unw_cursor_t& cursor) {
std::string res;
unw_word_t offp;
char data[256];
const int ret = unw_get_proc_name (&cursor, data, sizeof(data) / sizeof(char), &offp);
if (ret == -UNW_ENOMEM) {
res.resize(sizeof(data) * 2);
do {
const int ret2 = unw_get_proc_name(&cursor, &res[0], res.size(), &offp);
if (ret2 == -UNW_ENOMEM) {
res.resize(res.size() * 2);
} else if (ret2 == 0) {
break;
} else {
res = data;
return res;
}
} while(1);
} else if (ret == 0) {
res = data;
} else {
return res;
}
boost::core::scoped_demangled_name demangled(res.data());
if (demangled.get()) {
res = demangled.get();
} else {
res.resize( std::strlen(res.data()) ); // Note: here res is \0 terminated, but size() not equal to strlen
}
return res;
}
};
}}} // namespace boost::stacktrace::detail
#endif // BOOST_STACKTRACE_DETAIL_BACKTRACE_HOLDER_LIBUNWIND_HPP

View File

@@ -0,0 +1,57 @@
// Copyright Antony Polukhin, 2016.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_STACKTRACE_DETAIL_BACKTRACE_HOLDER_LINUX_HPP
#define BOOST_STACKTRACE_DETAIL_BACKTRACE_HOLDER_LINUX_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <boost/core/demangle.hpp>
#include <dlfcn.h>
#include <execinfo.h>
namespace boost { namespace stacktrace { namespace detail {
struct backtrace_holder {
std::size_t frames_count;
BOOST_STATIC_CONSTEXPR std::size_t max_size = 100u;
void* buffer[max_size];
inline std::size_t size() const BOOST_NOEXCEPT {
return frames_count;
}
inline std::string get_frame(std::size_t frame) const {
std::string res;
if (frame >= frames_count) {
return res;
}
Dl_info dli;
if (!dladdr(buffer[frame], &dli)) {
return res;
}
if (dli.dli_sname) {
boost::core::scoped_demangled_name demangled(dli.dli_sname);
if (demangled.get()) {
res = demangled.get();
} else {
res = dli.dli_sname;
}
}
return res;
}
};
}}} // namespace boost::stacktrace::detail
#endif // BOOST_STACKTRACE_DETAIL_BACKTRACE_HOLDER_LINUX_HPP

View File

@@ -0,0 +1,30 @@
// Copyright Antony Polukhin, 2016.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_STACKTRACE_DETAIL_BACKTRACE_HOLDER_NOOP_HPP
#define BOOST_STACKTRACE_DETAIL_BACKTRACE_HOLDER_NOOP_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
namespace boost { namespace stacktrace { namespace detail {
struct backtrace_holder {
inline std::size_t size() const BOOST_NOEXCEPT {
return 0u;
}
inline std::string get_frame(std::size_t /*frame*/) const {
return std::string();
}
};
}}} // namespace boost::stacktrace::detail
#endif // BOOST_STACKTRACE_DETAIL_BACKTRACE_HOLDER_NOOP_HPP

View File

@@ -0,0 +1,86 @@
// Copyright Antony Polukhin, 2016.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_STACKTRACE_DETAIL_BACKTRACE_HOLDER_WINDOWS_HPP
#define BOOST_STACKTRACE_DETAIL_BACKTRACE_HOLDER_WINDOWS_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <windows.h>
#include "DbgHelp.h"
#include <WinBase.h>
#include <boost/detail/winapi/get_current_process.hpp>
#include <boost/detail/winapi/sym_from_addr.hpp>
#if !defined(BOOST_ALL_NO_LIB)
# define BOOST_LIB_NAME Dbghelp
# ifdef BOOST_STACKTRACE_DYN_LINK
# define BOOST_DYN_LINK
# endif
# include <boost/config/auto_link.hpp>
#endif
namespace boost { namespace stacktrace { namespace detail {
struct symbol_info_with_stack {
BOOST_STATIC_CONSTEXPR std::size_t max_name_length = MAX_SYM_NAME * sizeof(char);
boost::detail::winapi::SYMBOL_INFO_ symbol;
char name_part[max_name_length];
};
struct symbol_initialization_structure {
boost::detail::winapi::HANDLE_ process;
inline symbol_initialization_structure() BOOST_NOEXCEPT
: process(boost::detail::winapi::GetCurrentProcess())
{
SymInitialize(process, 0, true);
}
inline ~symbol_initialization_structure() BOOST_NOEXCEPT {
SymCleanup(process);
}
};
struct backtrace_holder {
BOOST_STATIC_CONSTEXPR std::size_t max_size = 100u;
std::size_t frames_count;
void* buffer[max_size];
inline std::size_t size() const BOOST_NOEXCEPT {
return frames_count;
}
inline std::string get_frame(std::size_t frame) const {
std::string res;
static symbol_initialization_structure symproc;
if (frame >= frames_count) {
return res;
}
symbol_info_with_stack s;
s.symbol.MaxNameLen = symbol_info_with_stack::max_name_length;
s.symbol.SizeOfStruct = sizeof(boost::detail::winapi::SYMBOL_INFO_);
const bool sym_res = !!boost::detail::winapi::SymFromAddr(
symproc.process, reinterpret_cast<boost::detail::winapi::ULONGLONG_>(buffer[frame]), 0, &s.symbol
);
if (sym_res) {
res = s.symbol.Name;
}
return res;
}
};
}}} // namespace boost::stacktrace::detail
#endif // BOOST_STACKTRACE_DETAIL_BACKTRACE_HOLDER_WINDOWS_HPP

View File

@@ -29,6 +29,15 @@ inline const boost::stacktrace::detail::backtrace_holder& to_bt(const T& data) B
return *reinterpret_cast<const boost::stacktrace::detail::backtrace_holder*>(&data);
}
template <class T>
inline boost::stacktrace::detail::backtrace_holder& construct_bt_and_return(T& data) BOOST_NOEXCEPT {
new (&data) boost::stacktrace::detail::backtrace_holder();
return boost::stacktrace::detail::to_bt(data);
}
inline boost::stacktrace::detail::backtrace_holder& construct_bt_and_return(backtrace_holder& data) BOOST_NOEXCEPT {
return data;
}
/*
BOOST_STATIC_CONSTEXPR char to_hex_array[] = "0123456789ABCDEF";

View File

@@ -13,35 +13,9 @@
#endif
#include <boost/stacktrace.hpp>
#include <boost/stacktrace/detail/stacktrace_helpers.hpp>
#include <boost/static_assert.hpp>
// Autodetection
#if !defined(BOOST_STACKTRACE_USE_NOOP) && !defined(BOOST_STACKTRACE_USE_WINDBG) && !defined(BOOST_STACKTRACE_USE_LIBUNWIND) \
&& !defined(BOOST_STACKTRACE_USE_BACKTRACE) &&!defined(BOOST_STACKTRACE_USE_HEADER)
#if defined(__has_include) && (!defined(__GNUC__) || __GNUC__ > 4 || BOOST_CLANG)
# if __has_include(<libunwind.h>)
# define BOOST_STACKTRACE_USE_LIBUNWIND
# elif __has_include(<execinfo.h>)
# define BOOST_STACKTRACE_USE_BACKTRACE
# elif __has_include("DbgHelp.h")
# define BOOST_STACKTRACE_USE_WINDBG
# endif
#else
# if defined(BOOST_WINDOWS)
# define BOOST_STACKTRACE_USE_WINDBG
# else
# define BOOST_STACKTRACE_USE_BACKTRACE
# endif
#endif
#endif
#if defined(BOOST_STACKTRACE_USE_HEADER)
# include BOOST_STACKTRACE_USE_HEADER
#elif defined(BOOST_STACKTRACE_USE_NOOP)
#if defined(BOOST_STACKTRACE_USE_NOOP)
# include <boost/stacktrace/detail/stacktrace_noop.hpp>
#elif defined(BOOST_STACKTRACE_USE_WINDBG)
# include <boost/stacktrace/detail/stacktrace_windows.hpp>
@@ -61,28 +35,23 @@ namespace boost { namespace stacktrace {
// requered to avoid `boost::stacktrace::detail::backtrace_holder` apearing in
// stack traces.
stacktrace::stacktrace(const stacktrace& bt) BOOST_NOEXCEPT {
new (&impl_) boost::stacktrace::detail::backtrace_holder(
boost::stacktrace::detail::to_bt(bt.impl_)
);
}
stacktrace::stacktrace(const stacktrace& bt) BOOST_NOEXCEPT
: impl_(bt.impl_)
{}
stacktrace& stacktrace::operator=(const stacktrace& bt) BOOST_NOEXCEPT {
boost::stacktrace::detail::to_bt(impl_) = boost::stacktrace::detail::to_bt(bt.impl_);
impl_ = bt.impl_;
return *this;
}
stacktrace::~stacktrace() BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG(sizeof(impl_) >= sizeof(boost::stacktrace::detail::backtrace_holder), "Too small storage for holding backtrace");
boost::stacktrace::detail::to_bt(impl_).~backtrace_holder();
}
stacktrace::~stacktrace() BOOST_NOEXCEPT {}
std::size_t stacktrace::size() const BOOST_NOEXCEPT {
return boost::stacktrace::detail::to_bt(impl_).size();
return impl_.size();
}
std::string stacktrace::operator[](std::size_t frame) const {
return boost::stacktrace::detail::to_bt(impl_).get_frame(frame);
return impl_.get_frame(frame);
}

View File

@@ -13,81 +13,13 @@
#endif
#include <boost/stacktrace.hpp>
#include <boost/stacktrace/detail/stacktrace_helpers.hpp>
#include <boost/core/demangle.hpp>
#include <cstring>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/make_shared.hpp>
#define UNW_LOCAL_ONLY
#include <libunwind.h>
namespace boost { namespace stacktrace { namespace detail {
struct backtrace_holder {
std::size_t frames_count;
boost::shared_ptr<std::string[]> frames;
BOOST_FORCEINLINE backtrace_holder() BOOST_NOEXCEPT
: frames_count(0)
{}
inline std::size_t size() const BOOST_NOEXCEPT {
return frames_count;
}
inline std::string get_frame(std::size_t frame) const {
if (frame < frames_count) {
return frames[frame];
} else {
return std::string();
}
}
static inline std::string get_frame_impl(unw_cursor_t& cursor) {
std::string res;
unw_word_t offp;
char data[256];
const int ret = unw_get_proc_name (&cursor, data, sizeof(data) / sizeof(char), &offp);
if (ret == -UNW_ENOMEM) {
res.resize(sizeof(data) * 2);
do {
const int ret2 = unw_get_proc_name(&cursor, &res[0], res.size(), &offp);
if (ret2 == -UNW_ENOMEM) {
res.resize(res.size() * 2);
} else if (ret2 == 0) {
break;
} else {
res = data;
return res;
}
} while(1);
} else if (ret == 0) {
res = data;
} else {
return res;
}
boost::core::scoped_demangled_name demangled(res.data());
if (demangled.get()) {
res = demangled.get();
} else {
res.resize( std::strlen(res.data()) ); // Note: here res is \0 terminated, but size() not equal to strlen
}
return res;
}
};
}}} // namespace boost::stacktrace::detail
#include <boost/stacktrace/detail/backtrace_holder_libunwind.hpp>
#include <boost/stacktrace/detail/helpers.hpp>
namespace boost { namespace stacktrace {
stacktrace::stacktrace() BOOST_NOEXCEPT {
new (&impl_) boost::stacktrace::detail::backtrace_holder();
boost::stacktrace::detail::backtrace_holder& bt = boost::stacktrace::detail::to_bt(impl_);
boost::stacktrace::detail::backtrace_holder& bt = boost::stacktrace::detail::construct_bt_and_return(impl_);
unw_context_t uc;
if (unw_getcontext(&uc) != 0) {

View File

@@ -13,55 +13,13 @@
#endif
#include <boost/stacktrace.hpp>
#include <boost/stacktrace/detail/stacktrace_helpers.hpp>
#include <boost/core/demangle.hpp>
#include <dlfcn.h>
#include <execinfo.h>
namespace boost { namespace stacktrace { namespace detail {
struct backtrace_holder {
std::size_t frames_count;
BOOST_STATIC_CONSTEXPR std::size_t max_size = 100u;
void* buffer[max_size];
inline std::size_t size() const BOOST_NOEXCEPT {
return frames_count;
}
inline std::string get_frame(std::size_t frame) const {
std::string res;
if (frame >= frames_count) {
return res;
}
Dl_info dli;
if (!dladdr(buffer[frame], &dli)) {
return res;
}
if (dli.dli_sname) {
boost::core::scoped_demangled_name demangled(dli.dli_sname);
if (demangled.get()) {
res = demangled.get();
} else {
res = dli.dli_sname;
}
}
return res;
}
};
}}} // namespace boost::stacktrace::detail
#include <boost/stacktrace/detail/backtrace_holder_linux.hpp>
#include <boost/stacktrace/detail/helpers.hpp>
namespace boost { namespace stacktrace {
stacktrace::stacktrace() BOOST_NOEXCEPT {
new (&impl_) boost::stacktrace::detail::backtrace_holder();
boost::stacktrace::detail::backtrace_holder& bt = boost::stacktrace::detail::to_bt(impl_);
boost::stacktrace::detail::backtrace_holder& bt = boost::stacktrace::detail::construct_bt_and_return(impl_);
bt.frames_count = ::backtrace(bt.buffer, boost::stacktrace::detail::backtrace_holder::max_size);
}

View File

@@ -12,27 +12,14 @@
# pragma once
#endif
#include <boost/stacktrace.hpp>
namespace boost { namespace stacktrace { namespace detail {
struct backtrace_holder {
inline std::size_t size() const BOOST_NOEXCEPT {
return 0u;
}
inline std::string get_frame(std::size_t /*frame*/) const {
return std::string();
}
};
}}} // namespace boost::stacktrace::detail
#include <boost/stacktrace/detail/backtrace_holder_noop.hpp>
#include <boost/stacktrace/detail/helpers.hpp>
namespace boost { namespace stacktrace {
stacktrace::stacktrace() BOOST_NOEXCEPT {
new (&impl_) boost::stacktrace::detail::backtrace_holder();
boost::stacktrace::detail::construct_bt_and_return(impl_);
}
}} // namespace boost::stacktrace

View File

@@ -13,84 +13,13 @@
#endif
#include <boost/stacktrace.hpp>
#include <boost/stacktrace/detail/stacktrace_helpers.hpp>
#include <windows.h>
#include "DbgHelp.h"
#include <WinBase.h>
#include <boost/detail/winapi/get_current_process.hpp>
#include <boost/detail/winapi/sym_from_addr.hpp>
#if !defined(BOOST_ALL_NO_LIB)
# define BOOST_LIB_NAME Dbghelp
# ifdef BOOST_STACKTRACE_DYN_LINK
# define BOOST_DYN_LINK
# endif
# include <boost/config/auto_link.hpp>
#endif
namespace boost { namespace stacktrace { namespace detail {
struct symbol_info_with_stack {
BOOST_STATIC_CONSTEXPR std::size_t max_name_length = MAX_SYM_NAME * sizeof(char);
boost::detail::winapi::SYMBOL_INFO_ symbol;
char name_part[max_name_length];
};
struct symbol_initialization_structure {
boost::detail::winapi::HANDLE_ process;
inline symbol_initialization_structure() BOOST_NOEXCEPT
: process(boost::detail::winapi::GetCurrentProcess())
{
SymInitialize(process, 0, true);
}
inline ~symbol_initialization_structure() BOOST_NOEXCEPT {
SymCleanup(process);
}
};
struct backtrace_holder {
BOOST_STATIC_CONSTEXPR std::size_t max_size = 100u;
std::size_t frames_count;
void* buffer[max_size];
inline std::size_t size() const BOOST_NOEXCEPT {
return frames_count;
}
inline std::string get_frame(std::size_t frame) const {
std::string res;
static symbol_initialization_structure symproc;
if (frame >= frames_count) {
return res;
}
symbol_info_with_stack s;
s.symbol.MaxNameLen = symbol_info_with_stack::max_name_length;
s.symbol.SizeOfStruct = sizeof(boost::detail::winapi::SYMBOL_INFO_);
const bool sym_res = !!boost::detail::winapi::SymFromAddr(
symproc.process, reinterpret_cast<boost::detail::winapi::ULONGLONG_>(buffer[frame]), 0, &s.symbol
);
if (sym_res) {
res = s.symbol.Name;
}
return res;
}
};
}}} // namespace boost::stacktrace::detail
#include <boost/stacktrace/detail/backtrace_holder_windows.hpp>
#include <boost/stacktrace/detail/helpers.hpp>
namespace boost { namespace stacktrace {
stacktrace::stacktrace() BOOST_NOEXCEPT {
new (&impl_) boost::stacktrace::detail::backtrace_holder();
boost::stacktrace::detail::backtrace_holder& bt = boost::stacktrace::detail::to_bt(impl_);
boost::stacktrace::detail::backtrace_holder& bt = boost::stacktrace::detail::construct_bt_and_return(impl_);
bt.frames_count = CaptureStackBackTrace(0, boost::stacktrace::detail::backtrace_holder::max_size, bt.buffer, 0);
}

View File

@@ -7,4 +7,4 @@
#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS
#define BOOST_STACKTRACE_USE_BACKTRACE
#define BOOST_STACKTRACE_LINK
#include <boost/stacktrace/detail/stacktrace.ipp>
#include "stacktrace_src.ipp"

View File

@@ -7,4 +7,4 @@
#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS
#define BOOST_STACKTRACE_USE_LIBUNWIND
#define BOOST_STACKTRACE_LINK
#include <boost/stacktrace/detail/stacktrace.ipp>
#include "stacktrace_src.ipp"

View File

@@ -7,4 +7,4 @@
#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS
#define BOOST_STACKTRACE_USE_NOOP
#define BOOST_STACKTRACE_LINK
#include <boost/stacktrace/detail/stacktrace.ipp>
#include "stacktrace_src.ipp"

73
src/stacktrace_src.ipp Normal file
View File

@@ -0,0 +1,73 @@
// Copyright Antony Polukhin, 2016.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_STACKTRACE_SRC_STACKTRACE_IPP
#define BOOST_STACKTRACE_SRC_STACKTRACE_IPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <boost/stacktrace.hpp>
#include <boost/static_assert.hpp>
#if defined(BOOST_STACKTRACE_USE_HEADER)
# include BOOST_STACKTRACE_USE_HEADER
#elif defined(BOOST_STACKTRACE_USE_NOOP)
# include <boost/stacktrace/detail/backtrace_holder_noop.hpp>
# include <boost/stacktrace/detail/stacktrace_noop.hpp>
#elif defined(BOOST_STACKTRACE_USE_WINDBG)
# include <boost/stacktrace/detail/backtrace_holder_windows.hpp>
# include <boost/stacktrace/detail/stacktrace_windows.hpp>
#elif defined(BOOST_STACKTRACE_USE_LIBUNWIND)
# include <boost/stacktrace/detail/backtrace_holder_libunwind.hpp>
# include <boost/stacktrace/detail/stacktrace_libunwind.hpp>
#elif defined(BOOST_STACKTRACE_USE_BACKTRACE)
# include <boost/stacktrace/detail/backtrace_holder_linux.hpp>
# include <boost/stacktrace/detail/stacktrace_linux.hpp>
#else
# error No suitable backtrace backend found
#endif
#include <boost/stacktrace/detail/helpers.hpp>
namespace boost { namespace stacktrace {
// stacktrace::stacktrace() is defined in each backend separately. This is
// requered to avoid `boost::stacktrace::detail::backtrace_holder` apearing in
// stack traces.
stacktrace::stacktrace(const stacktrace& bt) BOOST_NOEXCEPT {
new (&impl_) boost::stacktrace::detail::backtrace_holder(
boost::stacktrace::detail::to_bt(bt.impl_)
);
}
stacktrace& stacktrace::operator=(const stacktrace& bt) BOOST_NOEXCEPT {
boost::stacktrace::detail::to_bt(impl_) = boost::stacktrace::detail::to_bt(bt.impl_);
return *this;
}
stacktrace::~stacktrace() BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG(sizeof(impl_) >= sizeof(boost::stacktrace::detail::backtrace_holder), "Too small storage for holding backtrace");
boost::stacktrace::detail::to_bt(impl_).~backtrace_holder();
}
std::size_t stacktrace::size() const BOOST_NOEXCEPT {
return boost::stacktrace::detail::to_bt(impl_).size();
}
std::string stacktrace::operator[](std::size_t frame) const {
return boost::stacktrace::detail::to_bt(impl_).get_frame(frame);
}
}}
#endif // BOOST_STACKTRACE_SRC_STACKTRACE_IPP

View File

@@ -7,4 +7,4 @@
#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS
#define BOOST_STACKTRACE_USE_WINDBG
#define BOOST_STACKTRACE_LINK
#include <boost/stacktrace/detail/stacktrace.ipp>
#include "stacktrace_src.ipp"