mirror of
https://github.com/boostorg/stacktrace.git
synced 2026-01-27 07:22:09 +00:00
Minor improvements and refactoring
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
57
include/boost/stacktrace/detail/backtrace_holder_linux.hpp
Normal file
57
include/boost/stacktrace/detail/backtrace_holder_linux.hpp
Normal 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
|
||||
30
include/boost/stacktrace/detail/backtrace_holder_noop.hpp
Normal file
30
include/boost/stacktrace/detail/backtrace_holder_noop.hpp
Normal 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
|
||||
86
include/boost/stacktrace/detail/backtrace_holder_windows.hpp
Normal file
86
include/boost/stacktrace/detail/backtrace_holder_windows.hpp
Normal 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
|
||||
@@ -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";
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
73
src/stacktrace_src.ipp
Normal 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
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user