github.com/searKing/golang/go@v1.2.117/os/signal/cgo/include/boost/stacktrace/safe_dump_to.hpp (about) 1 // Copyright Antony Polukhin, 2016-2023. 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See 4 // accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 #ifndef BOOST_STACKTRACE_SAFE_DUMP_TO_HPP 8 #define BOOST_STACKTRACE_SAFE_DUMP_TO_HPP 9 10 #include <boost/config.hpp> 11 #ifdef BOOST_HAS_PRAGMA_ONCE 12 # pragma once 13 #endif 14 15 #if defined(BOOST_WINDOWS) 16 #include <boost/winapi/config.hpp> 17 #endif 18 19 #include <boost/stacktrace/detail/push_options.h> 20 21 #ifdef BOOST_INTEL 22 # pragma warning(push) 23 # pragma warning(disable:2196) // warning #2196: routine is both "inline" and "noinline" 24 #endif 25 26 /// @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*`, 27 /// so you could read them by using 'od -tx8 -An stacktrace_dump_failename' Linux command or using boost::stacktrace::stacktrace::from_dump functions. 28 29 namespace boost { namespace stacktrace { 30 31 /// @cond 32 namespace detail { 33 34 typedef const void* native_frame_ptr_t; // TODO: change to `typedef void(*native_frame_ptr_t)();` 35 enum helper{ max_frames_dump = 128 }; 36 37 BOOST_STACKTRACE_FUNCTION std::size_t from_dump(const char* filename, native_frame_ptr_t* out_frames); 38 BOOST_STACKTRACE_FUNCTION std::size_t dump(const char* file, const native_frame_ptr_t* frames, std::size_t frames_count) noexcept; 39 #if defined(BOOST_WINDOWS) 40 BOOST_STACKTRACE_FUNCTION std::size_t dump(void* fd, const native_frame_ptr_t* frames, std::size_t frames_count) noexcept; 41 #else 42 // POSIX 43 BOOST_STACKTRACE_FUNCTION std::size_t dump(int fd, const native_frame_ptr_t* frames, std::size_t frames_count) noexcept; 44 #endif 45 46 47 struct this_thread_frames { // struct is required to avoid warning about usage of inline+BOOST_NOINLINE 48 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; 49 50 BOOST_NOINLINE static std::size_t safe_dump_to_impl(void* memory, std::size_t size, std::size_t skip) noexcept { 51 typedef boost::stacktrace::detail::native_frame_ptr_t native_frame_ptr_t; 52 53 if (size < sizeof(native_frame_ptr_t)) { 54 return 0; 55 } 56 57 native_frame_ptr_t* mem = static_cast<native_frame_ptr_t*>(memory); 58 const std::size_t frames_count = boost::stacktrace::detail::this_thread_frames::collect(mem, size / sizeof(native_frame_ptr_t) - 1, skip + 1); 59 mem[frames_count] = 0; 60 return frames_count + 1; 61 } 62 63 template <class T> 64 BOOST_NOINLINE static std::size_t safe_dump_to_impl(T file, std::size_t skip, std::size_t max_depth) noexcept { 65 typedef boost::stacktrace::detail::native_frame_ptr_t native_frame_ptr_t; 66 67 native_frame_ptr_t buffer[boost::stacktrace::detail::max_frames_dump + 1]; 68 if (max_depth > boost::stacktrace::detail::max_frames_dump) { 69 max_depth = boost::stacktrace::detail::max_frames_dump; 70 } 71 72 const std::size_t frames_count = boost::stacktrace::detail::this_thread_frames::collect(buffer, max_depth, skip + 1); 73 buffer[frames_count] = 0; 74 return boost::stacktrace::detail::dump(file, buffer, frames_count + 1); 75 } 76 }; 77 78 } // namespace detail 79 /// @endcond 80 81 /// @brief Stores current function call sequence into the memory. 82 /// 83 /// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined. 84 /// 85 /// @b Async-Handler-Safety: Safe. 86 /// 87 /// @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) 88 /// 89 /// @param memory Preallocated buffer to store current function call sequence into. 90 /// 91 /// @param size Size of the preallocated buffer. 92 BOOST_FORCEINLINE std::size_t safe_dump_to(void* memory, std::size_t size) noexcept { 93 return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(memory, size, 0); 94 } 95 96 /// @brief Stores current function call sequence into the memory. 97 /// 98 /// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined. 99 /// 100 /// @b Async-Handler-Safety: Safe. 101 /// 102 /// @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) 103 /// 104 /// @param skip How many top calls to skip and do not store. 105 /// 106 /// @param memory Preallocated buffer to store current function call sequence into. 107 /// 108 /// @param size Size of the preallocated buffer. 109 BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, void* memory, std::size_t size) noexcept { 110 return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(memory, size, skip); 111 } 112 113 114 /// @brief Opens a file and rewrites its content with current function call sequence if such operations are async signal safe. 115 /// 116 /// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined. 117 /// 118 /// @b Async-Handler-Safety: Safe. 119 /// 120 /// @returns Stored call sequence depth including terminating zero frame. 121 /// 122 /// @param file File to store current function call sequence. 123 BOOST_FORCEINLINE std::size_t safe_dump_to(const char* file) noexcept { 124 return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(file, 0, boost::stacktrace::detail::max_frames_dump); 125 } 126 127 /// @brief Opens a file and rewrites its content with current function call sequence if such operations are async signal safe. 128 /// 129 /// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined. 130 /// 131 /// @b Async-Handler-Safety: Safe. 132 /// 133 /// @returns Stored call sequence depth including terminating zero frame. 134 /// 135 /// @param skip How many top calls to skip and do not store. 136 /// 137 /// @param max_depth Max call sequence depth to collect. 138 /// 139 /// @param file File to store current function call sequence. 140 BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, const char* file) noexcept { 141 return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(file, skip, max_depth); 142 } 143 144 #ifdef BOOST_STACKTRACE_DOXYGEN_INVOKED 145 146 /// @brief Writes into the provided file descriptor the current function call sequence if such operation is async signal safe. 147 /// 148 /// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined. 149 /// 150 /// @b Async-Handler-Safety: Safe. 151 /// 152 /// @returns Stored call sequence depth including terminating zero frame. 153 /// 154 /// @param file File to store current function call sequence. 155 BOOST_FORCEINLINE std::size_t safe_dump_to(platform_specific_descriptor fd) noexcept; 156 157 /// @brief Writes into the provided file descriptor the current function call sequence if such operation is async signal safe. 158 /// 159 /// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined. 160 /// 161 /// @b Async-Handler-Safety: Safe. 162 /// 163 /// @returns Stored call sequence depth including terminating zero frame. 164 /// 165 /// @param skip How many top calls to skip and do not store. 166 /// 167 /// @param max_depth Max call sequence depth to collect. 168 /// 169 /// @param file File to store current function call sequence. 170 BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, platform_specific_descriptor fd) noexcept; 171 172 #elif defined(BOOST_WINDOWS) 173 174 BOOST_FORCEINLINE std::size_t safe_dump_to(void* fd) noexcept { 175 return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, 0, boost::stacktrace::detail::max_frames_dump); 176 } 177 178 BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, void* fd) noexcept { 179 return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, skip, max_depth); 180 } 181 182 #else 183 184 // POSIX 185 BOOST_FORCEINLINE std::size_t safe_dump_to(int fd) noexcept { 186 return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, 0, boost::stacktrace::detail::max_frames_dump); 187 } 188 189 BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, int fd) noexcept { 190 return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, skip, max_depth); 191 } 192 193 #endif 194 195 196 }} // namespace boost::stacktrace 197 198 #ifdef BOOST_INTEL 199 # pragma warning(pop) 200 #endif 201 202 #include <boost/stacktrace/detail/pop_options.h> 203 204 #if !defined(BOOST_STACKTRACE_LINK) || defined(BOOST_STACKTRACE_INTERNAL_BUILD_LIBS) 205 # if defined(BOOST_STACKTRACE_USE_NOOP) 206 # include <boost/stacktrace/detail/safe_dump_noop.ipp> 207 # include <boost/stacktrace/detail/collect_noop.ipp> 208 # else 209 # if defined(BOOST_WINDOWS) 210 # include <boost/stacktrace/detail/safe_dump_win.ipp> 211 # else 212 # include <boost/stacktrace/detail/safe_dump_posix.ipp> 213 # endif 214 # if defined(BOOST_WINDOWS) && !defined(BOOST_WINAPI_IS_MINGW) // MinGW does not provide RtlCaptureStackBackTrace. MinGW-w64 does. 215 # include <boost/stacktrace/detail/collect_msvc.ipp> 216 # else 217 # include <boost/stacktrace/detail/collect_unwind.ipp> 218 # endif 219 # endif 220 #endif 221 222 #endif // BOOST_STACKTRACE_SAFE_DUMP_TO_HPP