Spicy
backtrace.h
1 // Copyright (c) 2020-now by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #if ! defined(_MSC_VER)
6 #include <cxxabi.h>
7 #endif
8 
9 #include <array>
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 namespace hilti::rt {
15 
17 class Backtrace {
18 public:
19  Backtrace();
20  Backtrace(const Backtrace& other) = default;
21  Backtrace(Backtrace&& other) = default;
22  ~Backtrace() = default;
23 
24  // Returns pointer to save stack space.
25  std::unique_ptr<std::vector<std::string>> backtrace() const;
26 
27  friend bool operator==(const Backtrace& a, const Backtrace& b);
28  friend bool operator!=(const Backtrace& a, const Backtrace& b) { return ! (a == b); }
29 
30  Backtrace& operator=(const Backtrace& other) = default;
31  Backtrace& operator=(Backtrace&& other) = default;
32 
33 private:
34  using Callstack = std::array<void*, 32>;
35  std::shared_ptr<Callstack> _callstack = nullptr;
36  int _frames = -1;
37 };
38 
39 bool operator==(const Backtrace& a, const Backtrace& b);
40 
42 inline std::string demangle(const std::string& symbol) {
43 #if defined(_MSC_VER)
44  // MSVC's typeid().name() returns "class X" or "struct X" prefixed names.
45  if ( symbol.starts_with("class ") )
46  return symbol.substr(6);
47  if ( symbol.starts_with("struct ") )
48  return symbol.substr(7);
49  if ( symbol.starts_with("enum ") )
50  return symbol.substr(5);
51  return symbol;
52 #else
53  int status;
54  char* dname = abi::__cxa_demangle(symbol.c_str(), nullptr, nullptr, &status);
55  std::string x = (dname && status == 0) ? dname : symbol;
56  if ( dname )
57  free(dname); // NOLINT
58 
59  return x;
60 #endif
61 }
62 
63 } // namespace hilti::rt
Definition: backtrace.h:17
Definition: any.h:7
std::string demangle(const std::string &symbol)
Definition: backtrace.h:42