1 #include "TRACE/trace.h"
2 #define TRACE_NAME "ExceptionStackTrace"
12 #include "ExceptionStackTrace.hh"
14 namespace artdaq::debug {
18 StackTraceCollector& getStackTraceCollector()
20 static StackTraceCollector collector = StackTraceCollector();
27 std::unique_ptr<char, void (*)(void*)> demangled_symbol(abi::__cxa_demangle(symbol.c_str(),
nullptr,
nullptr, &status), &std::free);
28 return status != 0 ? symbol : &*demangled_symbol;
33 std::ostringstream os;
34 os <<
'#' << index_ <<
" "
36 << filename_ <<
" : " << function_ <<
" + "
37 <<
"0x" << std::hex << offset_;
43 auto m = std::smatch();
45 if (std::regex_search(symbol_, m, std::regex{
"(\\S*)\\((|\\S+)\\)\\s\\[(0x\\S+)\\]"}) && m.size() == 4)
49 address_ =
static_cast<uintptr_t
>(stoull(m[3], 0, 16));
50 if (std::regex_search(function_, m, std::regex{
"(\\S+)\\+(\\S+)"}) && m.size() == 3)
52 std::string offstr = m[2];
54 offset_ =
static_cast<uintptr_t
>(stoull(offstr, 0, 16));
59 if (std::regex_search(symbol_, m, std::regex{
"(.*)\\("}) && m.size() == 2)
62 if (std::regex_search(symbol_, m, std::regex{
"[(](.*)[+]"}) && m.size() == 2)
65 if (std::regex_search(symbol_, m, std::regex{
"[+](0x\\S+)\\)"}) && m.size() == 2)
66 offset_ = static_cast<uintptr_t>(stoull(m[1], 0, 16));
68 if (std::regex_search(symbol_, m, std::regex{
"\\[(0x\\S+)\\]"}) && m.size() == 2)
69 address_ = static_cast<uintptr_t>(stoull(m[1], 0, 16));
74 : type_name_{std::move(type_name)}, traces_uptr_{
nullptr}, size_{::backtrace(frames_,
sizeof frames_ /
sizeof(
void*))}
80 traces_uptr_ = std::make_unique<traces_t>();
85 traces_uptr_->reserve(size_);
87 char** symbols = ::backtrace_symbols(frames_, size_);
89 for (
auto i = SKIP_HEAD; i < size_ - SKIP_TAIL; i++)
90 traces_uptr_->emplace_back(size_ - SKIP_TAIL - i, symbols[size_ - i - 1]);
94 for (
auto& trace : *traces_uptr_)
101 return "Error: Unresolved StackTrace, call resolve() first.";
105 std::cout <<
"Error: possibly corrupt stack.";
107 std::ostringstream os;
110 os <<
"Stack Trace: \n";
112 for (
auto const& trace : *traces_uptr_)
122 void __cxa_throw(
void* ex,
void* info,
void (*dest)(
void*))
124 artdaq::debug::getStackTraceCollector().
collect_stacktrace(static_cast<std::type_info*>(info)->name());
126 __cxa_throw_t* rethrow __attribute__((noreturn)) = (__cxa_throw_t*)dlsym(RTLD_NEXT,
"__cxa_throw");
128 rethrow(ex, info, dest);
131 __attribute__((noreturn)) void __cxa_throw(
void* ex, std::type_info* info,
void (*dest)(
void*))
135 auto* rethrow = (__cxa_throw_t*)dlsym(RTLD_NEXT,
"__cxa_throw");
137 rethrow(ex, info, dest);
static std::string demangle(std::string const &symbol)
Demangles backtrace symbols.
void resolve()
Reads and demangles backtrace symbols.
StackTrace(std::string type_name)
Constructor.
void resolve()
Reads and demangles backtrace symbols.
std::string print() const
Produces a stack trace summary.
void collect_stacktrace(Args &&...args)
Adds a stacktrace to the stack_traces_ map.
std::string print() const
Produces a one-line summary.