]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/stacktrace/safe_dump_to.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / stacktrace / safe_dump_to.hpp
CommitLineData
1e59de90 1// Copyright Antony Polukhin, 2016-2022.
b32b8144
FG
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
11fdf7f2
TL
15#if defined(BOOST_WINDOWS)
16#include <boost/winapi/config.hpp>
17#endif
18
b32b8144
FG
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
29namespace boost { namespace stacktrace {
30
31/// @cond
32namespace 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) BOOST_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) BOOST_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) BOOST_NOEXCEPT;
44#endif
45
46
47struct 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) BOOST_NOEXCEPT;
49
50 BOOST_NOINLINE static std::size_t safe_dump_to_impl(void* memory, std::size_t size, std::size_t skip) BOOST_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) BOOST_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///
92f5a8d4 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)
b32b8144
FG
88///
89/// @param memory Preallocated buffer to store current function call sequence into.
90///
91/// @param size Size of the preallocated buffer.
92BOOST_FORCEINLINE std::size_t safe_dump_to(void* memory, std::size_t size) BOOST_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///
92f5a8d4 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)
b32b8144
FG
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.
109BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, void* memory, std::size_t size) BOOST_NOEXCEPT {
110 return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(memory, size, skip);
111}
112
113
11fdf7f2 114/// @brief Opens a file and rewrites its content with current function call sequence if such operations are async signal safe.
b32b8144
FG
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.
123BOOST_FORCEINLINE std::size_t safe_dump_to(const char* file) BOOST_NOEXCEPT {
124 return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(file, 0, boost::stacktrace::detail::max_frames_dump);
125}
126
11fdf7f2 127/// @brief Opens a file and rewrites its content with current function call sequence if such operations are async signal safe.
b32b8144
FG
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.
140BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, const char* file) BOOST_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
11fdf7f2 146/// @brief Writes into the provided file descriptor the current function call sequence if such operation is async signal safe.
b32b8144
FG
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.
155BOOST_FORCEINLINE std::size_t safe_dump_to(platform_specific_descriptor fd) BOOST_NOEXCEPT;
156
11fdf7f2 157/// @brief Writes into the provided file descriptor the current function call sequence if such operation is async signal safe.
b32b8144
FG
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.
170BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, platform_specific_descriptor fd) BOOST_NOEXCEPT;
171
172#elif defined(BOOST_WINDOWS)
173
174BOOST_FORCEINLINE std::size_t safe_dump_to(void* fd) BOOST_NOEXCEPT {
175 return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, 0, boost::stacktrace::detail::max_frames_dump);
176}
177
178BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, void* fd) BOOST_NOEXCEPT {
179 return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, skip, max_depth);
180}
181
182#else
183
184// POSIX
185BOOST_FORCEINLINE std::size_t safe_dump_to(int fd) BOOST_NOEXCEPT {
186 return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, 0, boost::stacktrace::detail::max_frames_dump);
187}
188
189BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, int fd) BOOST_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