Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:52:31

0001 // Copyright Antony Polukhin, 2016-2023.
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See
0004 // accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_STACKTRACE_SAFE_DUMP_TO_HPP
0008 #define BOOST_STACKTRACE_SAFE_DUMP_TO_HPP
0009 
0010 #include <boost/config.hpp>
0011 #ifdef BOOST_HAS_PRAGMA_ONCE
0012 #   pragma once
0013 #endif
0014 
0015 #if defined(BOOST_WINDOWS)
0016 #include <boost/winapi/config.hpp>
0017 #endif
0018 
0019 #include <boost/stacktrace/detail/push_options.h>
0020 
0021 #ifdef BOOST_INTEL
0022 #   pragma warning(push)
0023 #   pragma warning(disable:2196) // warning #2196: routine is both "inline" and "noinline"
0024 #endif
0025 
0026 /// @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*`,
0027 /// so you could read them by using 'od -tx8 -An stacktrace_dump_failename' Linux command or using boost::stacktrace::stacktrace::from_dump functions.
0028 
0029 namespace boost { namespace stacktrace {
0030 
0031 /// @cond
0032 namespace detail {
0033 
0034     typedef const void* native_frame_ptr_t; // TODO: change to `typedef void(*native_frame_ptr_t)();`
0035     enum helper{ max_frames_dump = 128 };
0036 
0037     BOOST_STACKTRACE_FUNCTION std::size_t from_dump(const char* filename, native_frame_ptr_t* out_frames);
0038     BOOST_STACKTRACE_FUNCTION std::size_t dump(const char* file, const native_frame_ptr_t* frames, std::size_t frames_count) noexcept;
0039 #if defined(BOOST_WINDOWS)
0040     BOOST_STACKTRACE_FUNCTION std::size_t dump(void* fd, const native_frame_ptr_t* frames, std::size_t frames_count) noexcept;
0041 #else
0042     // POSIX
0043     BOOST_STACKTRACE_FUNCTION std::size_t dump(int fd, const native_frame_ptr_t* frames, std::size_t frames_count) noexcept;
0044 #endif
0045 
0046 
0047 struct this_thread_frames { // struct is required to avoid warning about usage of inline+BOOST_NOINLINE
0048     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) noexcept;
0049 
0050     BOOST_NOINLINE static std::size_t safe_dump_to_impl(void* memory, std::size_t size, std::size_t skip) noexcept {
0051         typedef boost::stacktrace::detail::native_frame_ptr_t native_frame_ptr_t;
0052 
0053         if (size < sizeof(native_frame_ptr_t)) {
0054             return 0;
0055         }
0056 
0057         native_frame_ptr_t* mem = static_cast<native_frame_ptr_t*>(memory);
0058         const std::size_t frames_count = boost::stacktrace::detail::this_thread_frames::collect(mem, size / sizeof(native_frame_ptr_t) - 1, skip + 1);
0059         mem[frames_count] = 0;
0060         return frames_count + 1;
0061     }
0062 
0063     template <class T>
0064     BOOST_NOINLINE static std::size_t safe_dump_to_impl(T file, std::size_t skip, std::size_t max_depth) noexcept {
0065         typedef boost::stacktrace::detail::native_frame_ptr_t native_frame_ptr_t;
0066 
0067         native_frame_ptr_t buffer[boost::stacktrace::detail::max_frames_dump + 1];
0068         if (max_depth > boost::stacktrace::detail::max_frames_dump) {
0069             max_depth = boost::stacktrace::detail::max_frames_dump;
0070         }
0071 
0072         const std::size_t frames_count = boost::stacktrace::detail::this_thread_frames::collect(buffer, max_depth, skip + 1);
0073         buffer[frames_count] = 0;
0074         return boost::stacktrace::detail::dump(file, buffer, frames_count + 1);
0075     }
0076 };
0077 
0078 } // namespace detail
0079 /// @endcond
0080 
0081 /// @brief Stores current function call sequence into the memory.
0082 ///
0083 /// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined.
0084 ///
0085 /// @b Async-Handler-Safety: Safe.
0086 ///
0087 /// @returns Stored call sequence depth including terminating zero frame. To get the actually consumed bytes multiply this value by the sizeof(boost::stacktrace::frame::native_frame_ptr_t)
0088 ///
0089 /// @param memory Preallocated buffer to store current function call sequence into.
0090 ///
0091 /// @param size Size of the preallocated buffer.
0092 BOOST_FORCEINLINE std::size_t safe_dump_to(void* memory, std::size_t size) noexcept {
0093     return  boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(memory, size, 0);
0094 }
0095 
0096 /// @brief Stores current function call sequence into the memory.
0097 ///
0098 /// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined.
0099 ///
0100 /// @b Async-Handler-Safety: Safe.
0101 ///
0102 /// @returns Stored call sequence depth including terminating zero frame.  To get the actually consumed bytes multiply this value by the sizeof(boost::stacktrace::frame::native_frame_ptr_t)
0103 ///
0104 /// @param skip How many top calls to skip and do not store.
0105 ///
0106 /// @param memory Preallocated buffer to store current function call sequence into.
0107 ///
0108 /// @param size Size of the preallocated buffer.
0109 BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, void* memory, std::size_t size) noexcept {
0110     return  boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(memory, size, skip);
0111 }
0112 
0113 
0114 /// @brief Opens a file and rewrites its content with current function call sequence if such operations are async signal safe.
0115 ///
0116 /// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined.
0117 ///
0118 /// @b Async-Handler-Safety: Safe.
0119 ///
0120 /// @returns Stored call sequence depth including terminating zero frame.
0121 ///
0122 /// @param file File to store current function call sequence.
0123 BOOST_FORCEINLINE std::size_t safe_dump_to(const char* file) noexcept {
0124     return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(file, 0, boost::stacktrace::detail::max_frames_dump);
0125 }
0126 
0127 /// @brief Opens a file and rewrites its content with current function call sequence if such operations are async signal safe.
0128 ///
0129 /// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined.
0130 ///
0131 /// @b Async-Handler-Safety: Safe.
0132 ///
0133 /// @returns Stored call sequence depth including terminating zero frame.
0134 ///
0135 /// @param skip How many top calls to skip and do not store.
0136 ///
0137 /// @param max_depth Max call sequence depth to collect.
0138 ///
0139 /// @param file File to store current function call sequence.
0140 BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, const char* file) noexcept {
0141     return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(file, skip, max_depth);
0142 }
0143 
0144 #ifdef BOOST_STACKTRACE_DOXYGEN_INVOKED
0145 
0146 /// @brief Writes into the provided file descriptor the current function call sequence if such operation is async signal safe.
0147 ///
0148 /// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined.
0149 ///
0150 /// @b Async-Handler-Safety: Safe.
0151 ///
0152 /// @returns Stored call sequence depth including terminating zero frame.
0153 ///
0154 /// @param file File to store current function call sequence.
0155 BOOST_FORCEINLINE std::size_t safe_dump_to(platform_specific_descriptor fd) noexcept;
0156 
0157 /// @brief Writes into the provided file descriptor the current function call sequence if such operation is async signal safe.
0158 ///
0159 /// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined.
0160 ///
0161 /// @b Async-Handler-Safety: Safe.
0162 ///
0163 /// @returns Stored call sequence depth including terminating zero frame.
0164 ///
0165 /// @param skip How many top calls to skip and do not store.
0166 ///
0167 /// @param max_depth Max call sequence depth to collect.
0168 ///
0169 /// @param file File to store current function call sequence.
0170 BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, platform_specific_descriptor fd) noexcept;
0171 
0172 #elif defined(BOOST_WINDOWS)
0173 
0174 BOOST_FORCEINLINE std::size_t safe_dump_to(void* fd) noexcept {
0175     return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, 0, boost::stacktrace::detail::max_frames_dump);
0176 }
0177 
0178 BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, void* fd) noexcept {
0179     return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, skip, max_depth);
0180 }
0181 
0182 #else
0183 
0184 // POSIX
0185 BOOST_FORCEINLINE std::size_t safe_dump_to(int fd) noexcept {
0186     return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, 0, boost::stacktrace::detail::max_frames_dump);
0187 }
0188 
0189 BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, int fd) noexcept {
0190     return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, skip, max_depth);
0191 }
0192 
0193 #endif
0194 
0195 
0196 }} // namespace boost::stacktrace
0197 
0198 #ifdef BOOST_INTEL
0199 #   pragma warning(pop)
0200 #endif
0201 
0202 #include <boost/stacktrace/detail/pop_options.h>
0203 
0204 #if !defined(BOOST_STACKTRACE_LINK) || defined(BOOST_STACKTRACE_INTERNAL_BUILD_LIBS)
0205 #   if defined(BOOST_STACKTRACE_USE_NOOP)
0206 #       include <boost/stacktrace/detail/safe_dump_noop.ipp>
0207 #       include <boost/stacktrace/detail/collect_noop.ipp>
0208 #   else
0209 #       if defined(BOOST_WINDOWS)
0210 #           include <boost/stacktrace/detail/safe_dump_win.ipp>
0211 #       else
0212 #           include <boost/stacktrace/detail/safe_dump_posix.ipp>
0213 #       endif
0214 #       if defined(BOOST_WINDOWS) && !defined(BOOST_WINAPI_IS_MINGW) // MinGW does not provide RtlCaptureStackBackTrace. MinGW-w64 does.
0215 #           include <boost/stacktrace/detail/collect_msvc.ipp>
0216 #       else
0217 #           include <boost/stacktrace/detail/collect_unwind.ipp>
0218 #       endif
0219 #   endif
0220 #endif
0221 
0222 #endif // BOOST_STACKTRACE_SAFE_DUMP_TO_HPP