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