Do not rely on BOOST_FORCEINLINE and just call all the backtrace retrival functions from stacktrace constructor

This commit is contained in:
Antony Polukhin
2016-09-26 19:45:14 +03:00
parent 45d2181fdd
commit decdb41e66
6 changed files with 93 additions and 60 deletions

View File

@@ -13,6 +13,7 @@
#endif
#include <boost/stacktrace.hpp>
#include <boost/stacktrace/detail/stacktrace_helpers.hpp>
#include <boost/static_assert.hpp>
// Autodetection
@@ -56,22 +57,9 @@
namespace boost { namespace stacktrace {
namespace detail {
template <class T>
inline boost::stacktrace::detail::backtrace_holder& to_bt(T& data) BOOST_NOEXCEPT {
return *reinterpret_cast<boost::stacktrace::detail::backtrace_holder*>(&data);
}
template <class T>
inline const boost::stacktrace::detail::backtrace_holder& to_bt(const T& data) BOOST_NOEXCEPT {
return *reinterpret_cast<const boost::stacktrace::detail::backtrace_holder*>(&data);
}
} // namespace detail
stacktrace::stacktrace() BOOST_NOEXCEPT {
new (&impl_) boost::stacktrace::detail::backtrace_holder();
}
// 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(

View File

@@ -16,6 +16,20 @@
#include <boost/type_traits/is_pointer.hpp>
namespace boost { namespace stacktrace { namespace detail {
struct backtrace_holder;
template <class T>
inline boost::stacktrace::detail::backtrace_holder& to_bt(T& data) BOOST_NOEXCEPT {
return *reinterpret_cast<boost::stacktrace::detail::backtrace_holder*>(&data);
}
template <class T>
inline const boost::stacktrace::detail::backtrace_holder& to_bt(const T& data) BOOST_NOEXCEPT {
return *reinterpret_cast<const boost::stacktrace::detail::backtrace_holder*>(&data);
}
/*
BOOST_STATIC_CONSTEXPR char to_hex_array[] = "0123456789ABCDEF";

View File

@@ -12,6 +12,7 @@
# pragma once
#endif
#include <boost/stacktrace.hpp>
#include <boost/stacktrace/detail/stacktrace_helpers.hpp>
#include <boost/core/demangle.hpp>
#include <cstring>
@@ -29,38 +30,7 @@ struct backtrace_holder {
BOOST_FORCEINLINE backtrace_holder() BOOST_NOEXCEPT
: frames_count(0)
{
unw_context_t uc;
if (unw_getcontext(&uc) != 0) {
return;
}
{ // Counting frames_count
unw_cursor_t cursor;
if (unw_init_local(&cursor, &uc) != 0) {
return;
}
while (unw_step(&cursor) > 0) {
++ frames_count;
}
}
unw_cursor_t cursor;
if (unw_init_local(&cursor, &uc) != 0) {
frames_count = 0;
return;
}
BOOST_TRY {
frames = boost::make_shared<std::string[]>(frames_count);
std::size_t i = 0;
while (unw_step(&cursor) > 0){
frames[i] = get_frame_impl(cursor);
++ i;
}
} BOOST_CATCH(...) {}
BOOST_CATCH_END
}
{}
inline std::size_t size() const BOOST_NOEXCEPT {
return frames_count;
@@ -112,4 +82,45 @@ struct backtrace_holder {
}}} // namespace boost::stacktrace::detail
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_);
unw_context_t uc;
if (unw_getcontext(&uc) != 0) {
return;
}
{ // Counting frames_count
unw_cursor_t cursor;
if (unw_init_local(&cursor, &uc) != 0) {
return;
}
while (unw_step(&cursor) > 0) {
++ bt.frames_count;
}
}
unw_cursor_t cursor;
if (unw_init_local(&cursor, &uc) != 0) {
bt.frames_count = 0;
return;
}
BOOST_TRY {
bt.frames = boost::make_shared<std::string[]>(bt.frames_count);
std::size_t i = 0;
while (unw_step(&cursor) > 0){
bt.frames[i] = boost::stacktrace::detail::backtrace_holder::get_frame_impl(cursor);
++ i;
}
} BOOST_CATCH(...) {}
BOOST_CATCH_END
}
}} // namespace boost::stacktrace
#endif // BOOST_STACKTRACE_DETAIL_STACKTRACE_LIBUNWIND_HPP

View File

@@ -26,10 +26,6 @@ struct backtrace_holder {
BOOST_STATIC_CONSTEXPR std::size_t max_size = 100u;
void* buffer[max_size];
BOOST_FORCEINLINE backtrace_holder() BOOST_NOEXCEPT {
frames_count = ::backtrace(buffer, max_size);
}
inline std::size_t size() const BOOST_NOEXCEPT {
return frames_count;
}
@@ -58,7 +54,17 @@ struct backtrace_holder {
}
};
}}} // namespace boost::stacktrace::detail
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_);
bt.frames_count = ::backtrace(bt.buffer, boost::stacktrace::detail::backtrace_holder::max_size);
}
}} // namespace boost::stacktrace
#endif // BOOST_STACKTRACE_DETAIL_STACKTRACE_LINUX_HPP

View File

@@ -12,6 +12,9 @@
# pragma once
#endif
#include <boost/stacktrace.hpp>
namespace boost { namespace stacktrace { namespace detail {
struct backtrace_holder {
@@ -26,4 +29,12 @@ struct backtrace_holder {
}}} // namespace boost::stacktrace::detail
namespace boost { namespace stacktrace {
stacktrace::stacktrace() BOOST_NOEXCEPT {
new (&impl_) boost::stacktrace::detail::backtrace_holder();
}
}} // namespace boost::stacktrace
#endif // BOOST_STACKTRACE_DETAIL_STACKTRACE_NOOP_HPP

View File

@@ -55,12 +55,6 @@ struct backtrace_holder {
std::size_t frames_count;
void* buffer[max_size];
BOOST_FORCEINLINE backtrace_holder() BOOST_NOEXCEPT
: frames_count(0)
{
frames_count = CaptureStackBackTrace(0, max_size, buffer, 0);
}
inline std::size_t size() const BOOST_NOEXCEPT {
return frames_count;
}
@@ -83,9 +77,18 @@ struct backtrace_holder {
}
return res;
}
};
}}} // namespace boost::stacktrace::detail
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_);
bt.frames_count = CaptureStackBackTrace(0, boost::stacktrace::detail::backtrace_holder::max_size, bt.buffer, 0);
}
}} // namespace boost::stacktrace
#endif // BOOST_STACKTRACE_DETAIL_STACKTRACE_WINDOWS_HPP