24#include <seastar/core/format.hh>
25#include <seastar/core/sstring.hh>
27#include <seastar/core/shared_ptr.hh>
28#include <seastar/util/modules.hh>
31#if __has_include(<execinfo.h>)
38#include <boost/container/static_vector.hpp>
39#include <fmt/ostream.h>
55bool operator==(
const frame& a,
const frame& b)
noexcept;
60frame decorate(uintptr_t addr)
noexcept;
64template<
typename Func>
65void backtrace(Func&& func)
noexcept(
noexcept(func(
frame()))) {
67 constexpr size_t max_backtrace = 100;
68 void* buffer[max_backtrace];
69 int n = ::backtrace(buffer, max_backtrace);
70 for (
int i = 0; i < n; ++i) {
71 auto ip =
reinterpret_cast<uintptr_t
>(buffer[i]);
72 func(decorate(ip - 1));
76#define SEASTAR_BACKTRACE_UNIMPLEMENTED
84 using vector_type = boost::container::static_vector<frame, 64>;
90 size_t calculate_hash()
const noexcept;
92 simple_backtrace(vector_type f,
char delimeter =
' ') noexcept : _frames(std::move(f)), _hash(calculate_hash()), _delimeter(delimeter) {}
95 size_t hash()
const noexcept {
return _hash; }
96 char delimeter()
const noexcept {
return _delimeter; }
101 return _hash == o._hash && _frames == o._frames;
105 return !(*
this == o);
113 const std::type_info* _task_type;
119 friend std::ostream& operator<<(std::ostream& out,
const task_entry&);
121 bool operator==(
const task_entry& o)
const noexcept {
122 return *_task_type == *o._task_type;
125 bool operator!=(
const task_entry& o)
const noexcept {
126 return !(*
this == o);
129 size_t hash()
const noexcept {
return _task_type->hash_code(); }
137 using entry = std::variant<shared_backtrace, task_entry>;
138 using vector_type = boost::container::static_vector<entry, 16>;
151 size_t hash()
const noexcept {
return _hash; }
152 char delimeter()
const noexcept {
return _main.delimeter(); }
154 friend std::ostream& operator<<(std::ostream& out,
const tasktrace&);
156 bool operator==(
const tasktrace& o)
const noexcept;
158 bool operator!=(
const tasktrace& o)
const noexcept {
159 return !(*
this == o);
185#if FMT_VERSION >= 90000
186template <>
struct fmt::formatter<
seastar::tasktrace> : fmt::ostream_formatter {};
187template <>
struct fmt::formatter<
seastar::simple_backtrace> : fmt::ostream_formatter {};
192using saved_backtrace = tasktrace;
194saved_backtrace current_backtrace() noexcept;
196tasktrace current_tasktrace() noexcept;
199simple_backtrace current_backtrace_tasklocal() noexcept;
201std::ostream& operator<<(
std::ostream& out, const tasktrace& b);
206class backtraced :
public Exc {
207 std::shared_ptr<sstring> _backtrace;
209 template<
typename... Args>
210 backtraced(Args&&... args)
211 : Exc(
std::forward<Args>(args)...)
212 , _backtrace(
std::make_shared<sstring>(
format(
"{} Backtrace: {}", Exc::what(), current_backtrace()))) {}
219 virtual const char* what() const noexcept
override {
221 return _backtrace->c_str();
236template <
class Exc,
typename... Args>
238 using exc_type = std::decay_t<Exc>;
239 static_assert(std::is_base_of_v<std::exception, exc_type>,
240 "throw_with_backtrace only works with exception types");
241 return std::make_exception_ptr<internal::backtraced<exc_type>>(Exc(std::forward<Args>(args)...));
254template <
class Exc,
typename... Args>
258 std::rethrow_exception(make_backtraced_exception_ptr<Exc>(std::forward<Args>(args)...));
Definition: shared_ptr.hh:268
Identifies function calls that are accounted as a group.
Definition: scheduling.hh:285
Definition: backtrace.hh:82
Definition: backtrace.hh:112
Definition: backtrace.hh:135
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
sstring format(fmt::format_string< A... > fmt, A &&... a)
Definition: format.hh:42
void throw_with_backtrace(Args &&... args)
Definition: backtrace.hh:257
std::exception_ptr make_backtraced_exception_ptr(Args &&... args)
Definition: backtrace.hh:237
Definition: backtrace.hh:50
Definition: backtrace.hh:44