24 #include <seastar/core/sstring.hh>
25 #include <seastar/core/print.hh>
27 #include <seastar/core/shared_ptr.hh>
28 #include <seastar/util/modules.hh>
30 #ifndef SEASTAR_MODULE
31 #if __has_include(<execinfo.h>)
38 #include <boost/container/static_vector.hpp>
54 bool operator==(
const frame& a,
const frame& b) noexcept;
59 frame decorate(uintptr_t addr) noexcept;
63 template<
typename Func>
64 void backtrace(Func&& func) noexcept(noexcept(func(
frame()))) {
66 constexpr
size_t max_backtrace = 100;
67 void* buffer[max_backtrace];
68 int n = ::backtrace(buffer, max_backtrace);
69 for (
int i = 0; i < n; ++i) {
70 auto ip =
reinterpret_cast<uintptr_t
>(buffer[i]);
71 func(decorate(ip - 1));
75 #define SEASTAR_BACKTRACE_UNIMPLEMENTED
83 using vector_type = boost::container::static_vector<frame, 64>;
89 size_t calculate_hash()
const noexcept;
92 simple_backtrace(vector_type f,
char delimeter =
' ') noexcept : _frames(std::move(f)), _delimeter(delimeter) {}
94 size_t hash()
const noexcept {
return _hash; }
95 char delimeter()
const noexcept {
return _delimeter; }
100 return _hash == o._hash && _frames == o._frames;
104 return !(*
this == o);
112 const std::type_info* _task_type;
118 friend std::ostream& operator<<(std::ostream& out,
const task_entry&);
120 bool operator==(
const task_entry& o)
const noexcept {
121 return *_task_type == *o._task_type;
124 bool operator!=(
const task_entry& o)
const noexcept {
125 return !(*
this == o);
128 size_t hash()
const noexcept {
return _task_type->hash_code(); }
133 SEASTAR_MODULE_EXPORT
136 using entry = std::variant<shared_backtrace, task_entry>;
137 using vector_type = boost::container::static_vector<entry, 16>;
150 size_t hash()
const noexcept {
return _hash; }
151 char delimeter()
const noexcept {
return _main.delimeter(); }
153 friend std::ostream& operator<<(std::ostream& out,
const tasktrace&);
155 bool operator==(
const tasktrace& o)
const noexcept;
157 bool operator!=(
const tasktrace& o)
const noexcept {
158 return !(*
this == o);
166 SEASTAR_MODULE_EXPORT
174 SEASTAR_MODULE_EXPORT
184 #if FMT_VERSION >= 90000
185 template <>
struct fmt::formatter<
seastar::tasktrace> : fmt::ostream_formatter {};
186 template <>
struct fmt::formatter<
seastar::simple_backtrace> : fmt::ostream_formatter {};
191 using saved_backtrace = tasktrace;
193 saved_backtrace current_backtrace() noexcept;
195 tasktrace current_tasktrace() noexcept;
198 simple_backtrace current_backtrace_tasklocal() noexcept;
200 std::ostream& operator<<(std::ostream& out, const tasktrace& b);
205 class backtraced :
public Exc {
206 std::shared_ptr<sstring> _backtrace;
208 template<
typename... Args>
209 backtraced(Args&&... args)
210 : Exc(std::forward<Args>(args)...)
211 , _backtrace(std::make_shared<sstring>(
format(
"{} Backtrace: {}", Exc::what(), current_backtrace()))) {}
218 virtual const char* what() const noexcept
override {
220 return _backtrace->c_str();
234 SEASTAR_MODULE_EXPORT
235 template <
class Exc,
typename... Args>
237 using exc_type = std::decay_t<Exc>;
238 static_assert(std::is_base_of_v<std::exception, exc_type>,
239 "throw_with_backtrace only works with exception types");
240 return std::make_exception_ptr<internal::backtraced<exc_type>>(Exc(std::forward<Args>(args)...));
252 SEASTAR_MODULE_EXPORT
253 template <
class Exc,
typename... Args>
257 std::rethrow_exception(make_backtraced_exception_ptr<Exc>(std::forward<Args>(args)...));
Definition: shared_ptr.hh:270
Identifies function calls that are accounted as a group.
Definition: scheduling.hh:286
Definition: backtrace.hh:81
Definition: backtrace.hh:111
Definition: backtrace.hh:134
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
void throw_with_backtrace(Args &&... args)
Definition: backtrace.hh:256
sstring format(const char *fmt, A &&... a)
Definition: print.hh:142
std::exception_ptr make_backtraced_exception_ptr(Args &&... args)
Definition: backtrace.hh:236
Definition: backtrace.hh:49
Definition: backtrace.hh:43