Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-14 08:47:48

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