From decdb41e66f929662da61bd5fc84cfc44d4a41f9 Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Mon, 26 Sep 2016 19:45:14 +0300 Subject: [PATCH] Do not rely on BOOST_FORCEINLINE and just call all the backtrace retrival functions from stacktrace constructor --- .../boost/stacktrace/detail/stacktrace.ipp | 20 +---- .../stacktrace/detail/stacktrace_helpers.hpp | 14 ++++ .../detail/stacktrace_libunwind.hpp | 75 +++++++++++-------- .../stacktrace/detail/stacktrace_linux.hpp | 16 ++-- .../stacktrace/detail/stacktrace_noop.hpp | 11 +++ .../stacktrace/detail/stacktrace_windows.hpp | 17 +++-- 6 files changed, 93 insertions(+), 60 deletions(-) diff --git a/include/boost/stacktrace/detail/stacktrace.ipp b/include/boost/stacktrace/detail/stacktrace.ipp index 7798d66..209113a 100644 --- a/include/boost/stacktrace/detail/stacktrace.ipp +++ b/include/boost/stacktrace/detail/stacktrace.ipp @@ -13,6 +13,7 @@ #endif #include +#include #include // Autodetection @@ -56,22 +57,9 @@ namespace boost { namespace stacktrace { -namespace detail { - template - inline boost::stacktrace::detail::backtrace_holder& to_bt(T& data) BOOST_NOEXCEPT { - return *reinterpret_cast(&data); - } - - template - inline const boost::stacktrace::detail::backtrace_holder& to_bt(const T& data) BOOST_NOEXCEPT { - return *reinterpret_cast(&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( diff --git a/include/boost/stacktrace/detail/stacktrace_helpers.hpp b/include/boost/stacktrace/detail/stacktrace_helpers.hpp index bd190ea..fe2bea4 100644 --- a/include/boost/stacktrace/detail/stacktrace_helpers.hpp +++ b/include/boost/stacktrace/detail/stacktrace_helpers.hpp @@ -16,6 +16,20 @@ #include namespace boost { namespace stacktrace { namespace detail { + +struct backtrace_holder; + +template +inline boost::stacktrace::detail::backtrace_holder& to_bt(T& data) BOOST_NOEXCEPT { + return *reinterpret_cast(&data); +} + +template +inline const boost::stacktrace::detail::backtrace_holder& to_bt(const T& data) BOOST_NOEXCEPT { + return *reinterpret_cast(&data); +} + + /* BOOST_STATIC_CONSTEXPR char to_hex_array[] = "0123456789ABCDEF"; diff --git a/include/boost/stacktrace/detail/stacktrace_libunwind.hpp b/include/boost/stacktrace/detail/stacktrace_libunwind.hpp index 547a17e..d97ad23 100644 --- a/include/boost/stacktrace/detail/stacktrace_libunwind.hpp +++ b/include/boost/stacktrace/detail/stacktrace_libunwind.hpp @@ -12,6 +12,7 @@ # pragma once #endif +#include #include #include #include @@ -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(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(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 diff --git a/include/boost/stacktrace/detail/stacktrace_linux.hpp b/include/boost/stacktrace/detail/stacktrace_linux.hpp index 3fcf15c..73a6fcc 100644 --- a/include/boost/stacktrace/detail/stacktrace_linux.hpp +++ b/include/boost/stacktrace/detail/stacktrace_linux.hpp @@ -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 diff --git a/include/boost/stacktrace/detail/stacktrace_noop.hpp b/include/boost/stacktrace/detail/stacktrace_noop.hpp index f7638d5..56a8270 100644 --- a/include/boost/stacktrace/detail/stacktrace_noop.hpp +++ b/include/boost/stacktrace/detail/stacktrace_noop.hpp @@ -12,6 +12,9 @@ # pragma once #endif + +#include + 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 diff --git a/include/boost/stacktrace/detail/stacktrace_windows.hpp b/include/boost/stacktrace/detail/stacktrace_windows.hpp index f70aafe..a5690de 100644 --- a/include/boost/stacktrace/detail/stacktrace_windows.hpp +++ b/include/boost/stacktrace/detail/stacktrace_windows.hpp @@ -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