diff --git a/build/has_addr2line.cpp b/build/has_addr2line.cpp index f91bc3c..232d687 100644 --- a/build/has_addr2line.cpp +++ b/build/has_addr2line.cpp @@ -7,13 +7,15 @@ #include #include +#include + #include #include int main() { #ifdef BOOST_STACKTRACE_ADDR2LINE_LOCATION - std::string s = BOOST_STACKTRACE_ADDR2LINE_LOCATION " -h"; + std::string s = BOOST_STRINGIZE( BOOST_STACKTRACE_ADDR2LINE_LOCATION ); " -h"; #else std::string s = "/usr/bin/addr2line -h"; #endif diff --git a/include/boost/stacktrace/detail/addr2line_impls.hpp b/include/boost/stacktrace/detail/addr2line_impls.hpp index 1c4cdc9..e314fe9 100644 --- a/include/boost/stacktrace/detail/addr2line_impls.hpp +++ b/include/boost/stacktrace/detail/addr2line_impls.hpp @@ -46,11 +46,10 @@ public: { int pdes[2]; #ifdef BOOST_STACKTRACE_ADDR2LINE_LOCATION - char prog_name[] = BOOST_STACKTRACE_ADDR2LINE_LOCATION ; - + char prog_name[] = BOOST_STRINGIZE( BOOST_STACKTRACE_ADDR2LINE_LOCATION ); #if !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_STATIC_ASSERT) static_assert( - boost::stacktrace::detail::is_abs_path( BOOST_STACKTRACE_ADDR2LINE_LOCATION ), + boost::stacktrace::detail::is_abs_path( BOOST_STRINGIZE( BOOST_STACKTRACE_ADDR2LINE_LOCATION ) ), "BOOST_STACKTRACE_ADDR2LINE_LOCATION must be an absolute path" ); #endif diff --git a/include/boost/stacktrace/detail/collect_msvc.ipp b/include/boost/stacktrace/detail/collect_msvc.ipp new file mode 100644 index 0000000..fadfb1f --- /dev/null +++ b/include/boost/stacktrace/detail/collect_msvc.ipp @@ -0,0 +1,33 @@ +// Copyright Antony Polukhin, 2016-2017. +// +// 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_COLLECT_MSVC_IPP +#define BOOST_STACKTRACE_DETAIL_COLLECT_MSVC_IPP + +#include +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +#include + +#include + +namespace boost { namespace stacktrace { namespace detail { + +std::size_t this_thread_frames::collect(native_frame_ptr_t* out_frames, std::size_t max_frames_count, std::size_t skip) BOOST_NOEXCEPT { + return ::CaptureStackBackTrace( + skip, + static_cast(max_frames_count), + out_frames, + 0 + ); +} + + +}}} // namespace boost::stacktrace + +#endif // BOOST_STACKTRACE_DETAIL_COLLECT_MSVC_IPP diff --git a/include/boost/stacktrace/detail/collect_noop.ipp b/include/boost/stacktrace/detail/collect_noop.ipp new file mode 100644 index 0000000..bcfae4c --- /dev/null +++ b/include/boost/stacktrace/detail/collect_noop.ipp @@ -0,0 +1,25 @@ +// Copyright Antony Polukhin, 2016-2017. +// +// 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_COLLECT_NOOP_IPP +#define BOOST_STACKTRACE_DETAIL_COLLECT_NOOP_IPP + +#include +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +#include + +namespace boost { namespace stacktrace { namespace detail { + +std::size_t this_thread_frames::collect(native_frame_ptr_t* /*out_frames*/, std::size_t /*max_frames_count*/, std::size_t /*skip*/) BOOST_NOEXCEPT { + return 0; +} + +}}} // namespace boost::stacktrace::detail + +#endif // BOOST_STACKTRACE_DETAIL_COLLECT_NOOP_IPP diff --git a/include/boost/stacktrace/detail/collect_unwind.ipp b/include/boost/stacktrace/detail/collect_unwind.ipp new file mode 100644 index 0000000..1adbba0 --- /dev/null +++ b/include/boost/stacktrace/detail/collect_unwind.ipp @@ -0,0 +1,66 @@ +// Copyright Antony Polukhin, 2016-2017. +// +// 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_COLLECT_UNWIND_IPP +#define BOOST_STACKTRACE_DETAIL_COLLECT_UNWIND_IPP + +#include +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +#include + +#include +#include + +namespace boost { namespace stacktrace { namespace detail { + +struct unwind_state { + std::size_t frames_to_skip; + native_frame_ptr_t* current; + native_frame_ptr_t* end; +}; + +inline _Unwind_Reason_Code unwind_callback(::_Unwind_Context* context, void* arg) { + unwind_state* const state = static_cast(arg); + if (state->frames_to_skip) { + --state->frames_to_skip; + return ::_Unwind_GetIP(context) ? ::_URC_NO_REASON : ::_URC_END_OF_STACK; + } + + *state->current = reinterpret_cast( + ::_Unwind_GetIP(context) + ); + + ++state->current; + if (!*(state->current - 1) || state->current == state->end) { + return ::_URC_END_OF_STACK; + } + return ::_URC_NO_REASON; +} + +std::size_t this_thread_frames::collect(native_frame_ptr_t* out_frames, std::size_t max_frames_count, std::size_t skip) BOOST_NOEXCEPT { + std::size_t frames_count = 0; + if (!max_frames_count) { + return frames_count; + } + + boost::stacktrace::detail::unwind_state state = { skip + 1, out_frames, out_frames + max_frames_count }; + ::_Unwind_Backtrace(&boost::stacktrace::detail::unwind_callback, &state); + frames_count = state.current - out_frames; + + if (frames_count && out_frames[frames_count - 1] == 0) { + -- frames_count; + } + + return frames_count; +} + + +}}} // namespace boost::stacktrace::detail + +#endif // BOOST_STACKTRACE_DETAIL_COLLECT_UNWIND_IPP diff --git a/include/boost/stacktrace/detail/frame_msvc.ipp b/include/boost/stacktrace/detail/frame_msvc.ipp index c9d7bff..dc58a61 100644 --- a/include/boost/stacktrace/detail/frame_msvc.ipp +++ b/include/boost/stacktrace/detail/frame_msvc.ipp @@ -28,11 +28,6 @@ # pragma comment(lib, "Dbgeng.lib") #endif -#ifdef BOOST_WINDOWS -# include -#else -# include -#endif #ifdef __CRT_UUID_DECL // for __MINGW32__ __CRT_UUID_DECL(IDebugClient,0x27fe5639,0x8407,0x4f47,0x83,0x64,0xee,0x11,0x8f,0xb0,0x8a,0xc8); @@ -51,15 +46,6 @@ namespace boost { namespace stacktrace { namespace detail { -std::size_t this_thread_frames::collect(native_frame_ptr_t* out_frames, std::size_t max_frames_count, std::size_t skip) BOOST_NOEXCEPT { - return ::CaptureStackBackTrace( - skip, - static_cast(max_frames_count), - out_frames, - 0 - ); -} - class com_global_initer: boost::noncopyable { bool ok_; diff --git a/include/boost/stacktrace/detail/frame_noop.ipp b/include/boost/stacktrace/detail/frame_noop.ipp index 8a94f87..b9b1b98 100644 --- a/include/boost/stacktrace/detail/frame_noop.ipp +++ b/include/boost/stacktrace/detail/frame_noop.ipp @@ -20,25 +20,6 @@ std::string to_string(const frame* /*frames*/, std::size_t /*count*/) { return std::string(); } -std::size_t this_thread_frames::collect(native_frame_ptr_t* /*out_frames*/, std::size_t /*max_frames_count*/, std::size_t /*skip*/) BOOST_NOEXCEPT { - return 0; -} - -#if defined(BOOST_WINDOWS) -std::size_t dump(void* /*fd*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) BOOST_NOEXCEPT { - return 0; -} -#else -std::size_t dump(int /*fd*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) BOOST_NOEXCEPT { - return 0; -} -#endif - - -std::size_t dump(const char* /*file*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) BOOST_NOEXCEPT { - return 0; -} - } // namespace detail std::string frame::name() const { diff --git a/include/boost/stacktrace/detail/frame_unwind.ipp b/include/boost/stacktrace/detail/frame_unwind.ipp index b8e44fc..d4e7973 100644 --- a/include/boost/stacktrace/detail/frame_unwind.ipp +++ b/include/boost/stacktrace/detail/frame_unwind.ipp @@ -19,7 +19,6 @@ #include #include -#include #include #ifdef BOOST_STACKTRACE_USE_BACKTRACE @@ -30,55 +29,8 @@ # include #endif -#ifdef BOOST_WINDOWS -# include -#else -# include -#endif - namespace boost { namespace stacktrace { namespace detail { -struct unwind_state { - std::size_t frames_to_skip; - native_frame_ptr_t* current; - native_frame_ptr_t* end; -}; - -inline _Unwind_Reason_Code unwind_callback(::_Unwind_Context* context, void* arg) { - unwind_state* const state = static_cast(arg); - if (state->frames_to_skip) { - --state->frames_to_skip; - return ::_Unwind_GetIP(context) ? ::_URC_NO_REASON : ::_URC_END_OF_STACK; - } - - *state->current = reinterpret_cast( - ::_Unwind_GetIP(context) - ); - - ++state->current; - if (!*(state->current - 1) || state->current == state->end) { - return ::_URC_END_OF_STACK; - } - return ::_URC_NO_REASON; -} - -std::size_t this_thread_frames::collect(native_frame_ptr_t* out_frames, std::size_t max_frames_count, std::size_t skip) BOOST_NOEXCEPT { - std::size_t frames_count = 0; - if (!max_frames_count) { - return frames_count; - } - - boost::stacktrace::detail::unwind_state state = { skip + 1, out_frames, out_frames + max_frames_count }; - ::_Unwind_Backtrace(&boost::stacktrace::detail::unwind_callback, &state); - frames_count = state.current - out_frames; - - if (frames_count && out_frames[frames_count - 1] == 0) { - -- frames_count; - } - - return frames_count; -} - template class to_string_impl_base: private Base { public: diff --git a/include/boost/stacktrace/detail/pop_options.pp b/include/boost/stacktrace/detail/pop_options.pp new file mode 100644 index 0000000..8995b00 --- /dev/null +++ b/include/boost/stacktrace/detail/pop_options.pp @@ -0,0 +1,12 @@ +// Copyright Antony Polukhin, 2016-2017. +// +// 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) + +// No include guards! Intentionally. + +#ifdef BOOST_STACKTRACE_FUNCTION +# undef BOOST_STACKTRACE_FUNCTION +#endif + diff --git a/include/boost/stacktrace/detail/push_options.pp b/include/boost/stacktrace/detail/push_options.pp new file mode 100644 index 0000000..3adb626 --- /dev/null +++ b/include/boost/stacktrace/detail/push_options.pp @@ -0,0 +1,31 @@ +// Copyright Antony Polukhin, 2016-2017. +// +// 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) + +// No include guards! Intentionally. + +// Link or header only +#if !defined(BOOST_STACKTRACE_LINK) && defined(BOOST_STACKTRACE_DYN_LINK) +# define BOOST_STACKTRACE_LINK +#endif + +#if defined(BOOST_STACKTRACE_LINK) && !defined(BOOST_STACKTRACE_DYN_LINK) && defined(BOOST_ALL_DYN_LINK) +# define BOOST_STACKTRACE_DYN_LINK +#endif + +#ifdef BOOST_STACKTRACE_LINK +# if defined(BOOST_STACKTRACE_DYN_LINK) +# ifdef BOOST_STACKTRACE_INTERNAL_BUILD_LIBS +# define BOOST_STACKTRACE_FUNCTION BOOST_SYMBOL_EXPORT +# else +# define BOOST_STACKTRACE_FUNCTION BOOST_SYMBOL_IMPORT +# endif +# else +# define BOOST_STACKTRACE_FUNCTION +# endif +#elif !defined(BOOST_STACKTRACE_DOXYGEN_INVOKED) +# define BOOST_STACKTRACE_FUNCTION inline +#endif + diff --git a/include/boost/stacktrace/detail/safe_dump_noop.ipp b/include/boost/stacktrace/detail/safe_dump_noop.ipp new file mode 100644 index 0000000..78fdc3a --- /dev/null +++ b/include/boost/stacktrace/detail/safe_dump_noop.ipp @@ -0,0 +1,37 @@ +// Copyright Antony Polukhin, 2016-2017. +// +// 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_SAFE_DUMP_NOOP_IPP +#define BOOST_STACKTRACE_DETAIL_SAFE_DUMP_NOOP_IPP + +#include +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +#include + +namespace boost { namespace stacktrace { namespace detail { + + +#if defined(BOOST_WINDOWS) +std::size_t dump(void* /*fd*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) BOOST_NOEXCEPT { + return 0; +} +#else +std::size_t dump(int /*fd*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) BOOST_NOEXCEPT { + return 0; +} +#endif + + +std::size_t dump(const char* /*file*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) BOOST_NOEXCEPT { + return 0; +} + +}}} // namespace boost::stacktrace::detail + +#endif // BOOST_STACKTRACE_DETAIL_SAFE_DUMP_NOOP_IPP diff --git a/include/boost/stacktrace/frame.hpp b/include/boost/stacktrace/frame.hpp index 87801c9..2f762c6 100644 --- a/include/boost/stacktrace/frame.hpp +++ b/include/boost/stacktrace/frame.hpp @@ -17,54 +17,16 @@ #include -// Link or header only -#if !defined(BOOST_STACKTRACE_LINK) && defined(BOOST_STACKTRACE_DYN_LINK) -# define BOOST_STACKTRACE_LINK -#endif - -#if defined(BOOST_STACKTRACE_LINK) && !defined(BOOST_STACKTRACE_DYN_LINK) && defined(BOOST_ALL_DYN_LINK) -# define BOOST_STACKTRACE_DYN_LINK -#endif - -#ifdef BOOST_STACKTRACE_LINK -# if defined(BOOST_STACKTRACE_DYN_LINK) -# ifdef BOOST_STACKTRACE_INTERNAL_BUILD_LIBS -# define BOOST_STACKTRACE_FUNCTION BOOST_SYMBOL_EXPORT -# else -# define BOOST_STACKTRACE_FUNCTION BOOST_SYMBOL_IMPORT -# endif -# else -# define BOOST_STACKTRACE_FUNCTION -# endif -#elif !defined(BOOST_STACKTRACE_DOXYGEN_INVOKED) -# define BOOST_STACKTRACE_FUNCTION inline -#endif +#include namespace boost { namespace stacktrace { class frame; - namespace detail { BOOST_STACKTRACE_FUNCTION std::string to_string(const frame* frames, std::size_t size); typedef const void* native_frame_ptr_t; // TODO: change to `typedef void(*native_frame_ptr_t)();` - - enum helper{ max_frames_dump = 128 }; - BOOST_STACKTRACE_FUNCTION std::size_t from_dump(const char* filename, native_frame_ptr_t* out_frames); - BOOST_STACKTRACE_FUNCTION std::size_t dump(const char* file, const native_frame_ptr_t* frames, std::size_t frames_count) BOOST_NOEXCEPT; -#if defined(BOOST_WINDOWS) - BOOST_STACKTRACE_FUNCTION std::size_t dump(void* fd, const native_frame_ptr_t* frames, std::size_t frames_count) BOOST_NOEXCEPT; -#else - // POSIX - BOOST_STACKTRACE_FUNCTION std::size_t dump(int fd, const native_frame_ptr_t* frames, std::size_t frames_count) BOOST_NOEXCEPT; -#endif - - -struct this_thread_frames { // struct is required to avoid warning about usage of inline+BOOST_NOINLINE - BOOST_NOINLINE BOOST_STACKTRACE_FUNCTION static std::size_t collect(native_frame_ptr_t* out_frames, std::size_t max_frames_count, std::size_t skip) BOOST_NOEXCEPT; -}; - } // namespace detail /// Non-owning class that references the frame information stored inside the boost::stacktrace::stacktrace class. @@ -200,7 +162,7 @@ std::basic_ostream& operator<<(std::basic_ostream #ifndef BOOST_STACKTRACE_LINK # if defined(BOOST_STACKTRACE_USE_NOOP) diff --git a/include/boost/stacktrace/safe_dump_to.hpp b/include/boost/stacktrace/safe_dump_to.hpp index 6e96f0c..5b7e863 100644 --- a/include/boost/stacktrace/safe_dump_to.hpp +++ b/include/boost/stacktrace/safe_dump_to.hpp @@ -14,6 +14,7 @@ #include +#include /// @file safe_dump_to.hpp This header contains low-level async-signal-safe functions for dumping call stacks. Dumps are binary serialized arrays of `void*`, /// so you could read them by using 'od -tx8 -An stacktrace_dump_failename' Linux command or using boost::stacktrace::stacktrace::from_dump functions. @@ -23,31 +24,47 @@ namespace boost { namespace stacktrace { /// @cond namespace detail { - struct suppress_noinline_warnings { - BOOST_NOINLINE static std::size_t safe_dump_to_impl(void* memory, std::size_t size, std::size_t skip) BOOST_NOEXCEPT { - typedef boost::stacktrace::detail::native_frame_ptr_t native_frame_ptr_t; - native_frame_ptr_t* mem = static_cast(memory); - const std::size_t frames_count = boost::stacktrace::detail::this_thread_frames::collect(mem, size / sizeof(native_frame_ptr_t) - 1, skip + 1); - mem[frames_count] = 0; - return frames_count + 1; + enum helper{ max_frames_dump = 128 }; + + BOOST_STACKTRACE_FUNCTION std::size_t from_dump(const char* filename, native_frame_ptr_t* out_frames); + BOOST_STACKTRACE_FUNCTION std::size_t dump(const char* file, const native_frame_ptr_t* frames, std::size_t frames_count) BOOST_NOEXCEPT; +#if defined(BOOST_WINDOWS) + BOOST_STACKTRACE_FUNCTION std::size_t dump(void* fd, const native_frame_ptr_t* frames, std::size_t frames_count) BOOST_NOEXCEPT; +#else + // POSIX + BOOST_STACKTRACE_FUNCTION std::size_t dump(int fd, const native_frame_ptr_t* frames, std::size_t frames_count) BOOST_NOEXCEPT; +#endif + + +struct this_thread_frames { // struct is required to avoid warning about usage of inline+BOOST_NOINLINE + BOOST_NOINLINE BOOST_STACKTRACE_FUNCTION static std::size_t collect(native_frame_ptr_t* out_frames, std::size_t max_frames_count, std::size_t skip) BOOST_NOEXCEPT; + + BOOST_NOINLINE static std::size_t safe_dump_to_impl(void* memory, std::size_t size, std::size_t skip) BOOST_NOEXCEPT { + typedef boost::stacktrace::detail::native_frame_ptr_t native_frame_ptr_t; + + native_frame_ptr_t* mem = static_cast(memory); + const std::size_t frames_count = boost::stacktrace::detail::this_thread_frames::collect(mem, size / sizeof(native_frame_ptr_t) - 1, skip + 1); + mem[frames_count] = 0; + return frames_count + 1; + } + + template + BOOST_NOINLINE static std::size_t safe_dump_to_impl(T file, std::size_t skip, std::size_t max_depth) BOOST_NOEXCEPT { + typedef boost::stacktrace::detail::native_frame_ptr_t native_frame_ptr_t; + + native_frame_ptr_t buffer[boost::stacktrace::detail::max_frames_dump + 1]; + if (max_depth > boost::stacktrace::detail::max_frames_dump) { + max_depth = boost::stacktrace::detail::max_frames_dump; } - template - BOOST_NOINLINE static std::size_t safe_dump_to_impl(T file, std::size_t skip, std::size_t max_depth) BOOST_NOEXCEPT { - typedef boost::stacktrace::detail::native_frame_ptr_t native_frame_ptr_t; + const std::size_t frames_count = boost::stacktrace::detail::this_thread_frames::collect(buffer, max_depth, skip + 1); + buffer[frames_count] = 0; + return boost::stacktrace::detail::dump(file, buffer, frames_count + 1); + } +}; - native_frame_ptr_t buffer[boost::stacktrace::detail::max_frames_dump + 1]; - if (max_depth > boost::stacktrace::detail::max_frames_dump) { - max_depth = boost::stacktrace::detail::max_frames_dump; - } - - const std::size_t frames_count = boost::stacktrace::detail::this_thread_frames::collect(buffer, max_depth, skip + 1); - buffer[frames_count] = 0; - return boost::stacktrace::detail::dump(file, buffer, frames_count + 1); - } - }; -} +} // namespace detail /// @endcond /// @brief Stores current function call sequence into the memory. @@ -62,7 +79,7 @@ namespace detail { /// /// @param size Size of the preallocated buffer. BOOST_FORCEINLINE std::size_t safe_dump_to(void* memory, std::size_t size) BOOST_NOEXCEPT { - return boost::stacktrace::detail::suppress_noinline_warnings::safe_dump_to_impl(memory, size, 0); + return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(memory, size, 0); } /// @brief Stores current function call sequence into the memory. @@ -79,7 +96,7 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(void* memory, std::size_t size) BOOST /// /// @param size Size of the preallocated buffer. BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, void* memory, std::size_t size) BOOST_NOEXCEPT { - return boost::stacktrace::detail::suppress_noinline_warnings::safe_dump_to_impl(memory, size, skip); + return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(memory, size, skip); } @@ -93,7 +110,7 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, void* memory, std:: /// /// @param file File to store current function call sequence. BOOST_FORCEINLINE std::size_t safe_dump_to(const char* file) BOOST_NOEXCEPT { - return boost::stacktrace::detail::suppress_noinline_warnings::safe_dump_to_impl(file, 0, boost::stacktrace::detail::max_frames_dump); + return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(file, 0, boost::stacktrace::detail::max_frames_dump); } /// @brief Opens a file and rewrites its content with current function call sequence. @@ -110,7 +127,7 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(const char* file) BOOST_NOEXCEPT { /// /// @param file File to store current function call sequence. BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, const char* file) BOOST_NOEXCEPT { - return boost::stacktrace::detail::suppress_noinline_warnings::safe_dump_to_impl(file, skip, max_depth); + return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(file, skip, max_depth); } #ifdef BOOST_STACKTRACE_DOXYGEN_INVOKED @@ -144,22 +161,22 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_dep #elif defined(BOOST_WINDOWS) BOOST_FORCEINLINE std::size_t safe_dump_to(void* fd) BOOST_NOEXCEPT { - return boost::stacktrace::detail::suppress_noinline_warnings::safe_dump_to_impl(fd, 0, boost::stacktrace::detail::max_frames_dump); + return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, 0, boost::stacktrace::detail::max_frames_dump); } BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, void* fd) BOOST_NOEXCEPT { - return boost::stacktrace::detail::suppress_noinline_warnings::safe_dump_to_impl(fd, skip, max_depth); + return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, skip, max_depth); } #else // POSIX BOOST_FORCEINLINE std::size_t safe_dump_to(int fd) BOOST_NOEXCEPT { - return boost::stacktrace::detail::suppress_noinline_warnings::safe_dump_to_impl(fd, 0, boost::stacktrace::detail::max_frames_dump); + return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, 0, boost::stacktrace::detail::max_frames_dump); } BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, int fd) BOOST_NOEXCEPT { - return boost::stacktrace::detail::suppress_noinline_warnings::safe_dump_to_impl(fd, skip, max_depth); + return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, skip, max_depth); } #endif @@ -167,4 +184,24 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_dep }} // namespace boost::stacktrace +#include + +#if !defined(BOOST_STACKTRACE_LINK) || defined(BOOST_STACKTRACE_INTERNAL_BUILD_LIBS) +# if defined(BOOST_STACKTRACE_USE_NOOP) +# include +# include +# else +# if defined(BOOST_WINDOWS) +# include +# else +# include +# endif +# if defined(BOOST_MSVC) +# include +# else +# include +# endif +# endif +#endif + #endif // BOOST_STACKTRACE_SAFE_DUMP_TO_HPP diff --git a/include/boost/stacktrace/stacktrace.hpp b/include/boost/stacktrace/stacktrace.hpp index c8dc2c2..dc4aa9a 100644 --- a/include/boost/stacktrace/stacktrace.hpp +++ b/include/boost/stacktrace/stacktrace.hpp @@ -20,6 +20,7 @@ #include #include +#include /// @cond namespace boost { diff --git a/src/addr2line.cpp b/src/addr2line.cpp index 7360d41..05073ae 100644 --- a/src/addr2line.cpp +++ b/src/addr2line.cpp @@ -8,3 +8,4 @@ #define BOOST_STACKTRACE_USE_ADDR2LINE #define BOOST_STACKTRACE_LINK #include +#include diff --git a/src/backtrace.cpp b/src/backtrace.cpp index b9e9dc8..8b45821 100644 --- a/src/backtrace.cpp +++ b/src/backtrace.cpp @@ -8,3 +8,4 @@ #define BOOST_STACKTRACE_USE_BACKTRACE #define BOOST_STACKTRACE_LINK #include +#include diff --git a/src/basic.cpp b/src/basic.cpp index 4d6d928..5487f70 100644 --- a/src/basic.cpp +++ b/src/basic.cpp @@ -7,3 +7,4 @@ #define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS #define BOOST_STACKTRACE_LINK #include +#include diff --git a/src/noop.cpp b/src/noop.cpp index 232d2a4..e895eb2 100644 --- a/src/noop.cpp +++ b/src/noop.cpp @@ -6,4 +6,6 @@ #define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS #define BOOST_STACKTRACE_LINK +#define BOOST_STACKTRACE_USE_NOOP #include +#include diff --git a/src/windbg.cpp b/src/windbg.cpp index a6be578..ea1cf90 100644 --- a/src/windbg.cpp +++ b/src/windbg.cpp @@ -7,3 +7,4 @@ #define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS #define BOOST_STACKTRACE_LINK #include +#include diff --git a/src/windbg_cached.cpp b/src/windbg_cached.cpp index e76c6d3..fdf3a5d 100644 --- a/src/windbg_cached.cpp +++ b/src/windbg_cached.cpp @@ -8,3 +8,4 @@ #define BOOST_STACKTRACE_LINK #define BOOST_STACKTRACE_USE_WINDBG_CACHED #include +#include diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index aee5373..a95a572 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -115,11 +115,13 @@ test-suite stacktrace_tests # Header only tests without debug symbols [ run test.cpp test_impl.cpp : : : off BOOST_STACKTRACE_USE_BACKTRACE BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL $(BT_DEPS) : backtrace_ho_no_dbg ] - [ run test.cpp test_impl.cpp : : : off BOOST_STACKTRACE_USE_ADDR2LINE $(AD2L_DEPS) : addr2line_ho_no_dbg ] [ run test_noop.cpp test_impl.cpp : : : off BOOST_STACKTRACE_USE_NOOP $(NOOP_DEPS) : noop_ho_no_dbg ] [ run test.cpp test_impl.cpp : : : off BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL $(WIND_DEPS) : windbg_ho_no_dbg ] [ run test.cpp test_impl.cpp : : : off BOOST_STACKTRACE_USE_WINDBG_CACHED BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL $(WIND_DEPS) : windbg_cached_ho_no_dbg ] [ run test.cpp test_impl.cpp : : : off $(BASIC_DEPS) : basic_ho_no_dbg ] + [ run test.cpp test_impl.cpp + : : : off BOOST_STACKTRACE_USE_ADDR2LINE BOOST_STACKTRACE_ADDR2LINE_LOCATION="/usr/bin/addr2line" $(AD2L_DEPS) + : addr2line_ho_no_dbg ] # Test with shared linked implementations without debug symbols [ run test.cpp : : : off .//test_impl_lib_backtrace_no_dbg $(LINKSHARED_BT) BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL : backtrace_lib_no_dbg ]