/src/spicy/hilti/runtime/include/hilti/rt/backtrace.h
Line | Count | Source |
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 <cstdlib> |
11 | | #include <memory> |
12 | | #include <string> |
13 | | #include <vector> |
14 | | |
15 | | namespace hilti::rt { |
16 | | |
17 | | /** Captures a stack backtrace at construction time. */ |
18 | | class Backtrace { |
19 | | public: |
20 | | Backtrace(); |
21 | 0 | Backtrace(const Backtrace& other) = default; |
22 | 0 | Backtrace(Backtrace&& other) = default; |
23 | 0 | ~Backtrace() = default; |
24 | | |
25 | | // Returns pointer to save stack space. |
26 | | std::unique_ptr<std::vector<std::string>> backtrace() const; |
27 | | |
28 | | friend bool operator==(const Backtrace& a, const Backtrace& b); |
29 | 0 | friend bool operator!=(const Backtrace& a, const Backtrace& b) { return ! (a == b); } |
30 | | |
31 | 0 | Backtrace& operator=(const Backtrace& other) = default; |
32 | 0 | Backtrace& operator=(Backtrace&& other) = default; |
33 | | |
34 | | private: |
35 | | using Callstack = std::array<void*, 32>; |
36 | | std::shared_ptr<Callstack> _callstack = nullptr; |
37 | | int _frames = -1; |
38 | | }; |
39 | | |
40 | | bool operator==(const Backtrace& a, const Backtrace& b); |
41 | | |
42 | | /** Wrapper around the ABI's C++ demangle function. */ |
43 | 0 | inline std::string demangle(const std::string& symbol) { |
44 | | #if defined(_MSC_VER) |
45 | | // MSVC's typeid().name() returns "class X" or "struct X" prefixed names. |
46 | | if ( symbol.starts_with("class ") ) |
47 | | return symbol.substr(6); |
48 | | if ( symbol.starts_with("struct ") ) |
49 | | return symbol.substr(7); |
50 | | if ( symbol.starts_with("enum ") ) |
51 | | return symbol.substr(5); |
52 | | return symbol; |
53 | | #else |
54 | 0 | int status; |
55 | 0 | char* dname = abi::__cxa_demangle(symbol.c_str(), nullptr, nullptr, &status); |
56 | 0 | std::string x = (dname && status == 0) ? dname : symbol; |
57 | 0 | if ( dname ) |
58 | 0 | free(dname); // NOLINT |
59 | |
|
60 | 0 | return x; |
61 | 0 | #endif |
62 | 0 | } |
63 | | |
64 | | } // namespace hilti::rt |