line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#include "exception.h" |
2
|
|
|
|
|
|
|
#include |
3
|
|
|
|
|
|
|
#include |
4
|
|
|
|
|
|
|
#include |
5
|
|
|
|
|
|
|
#include |
6
|
|
|
|
|
|
|
#include |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
#if defined(__unix__) |
9
|
|
|
|
|
|
|
#include |
10
|
|
|
|
|
|
|
#endif |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
namespace panda { |
13
|
|
|
|
|
|
|
|
14
|
0
|
|
|
|
|
|
backtrace::backtrace (const backtrace& other) noexcept : buffer(other.buffer) {} |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
#if defined(__unix__) |
17
|
|
|
|
|
|
|
|
18
|
0
|
|
|
|
|
|
backtrace::backtrace () noexcept { |
19
|
0
|
|
|
|
|
|
buffer.resize(max_depth); |
20
|
0
|
|
|
|
|
|
auto depth = ::backtrace(buffer.data(), max_depth); |
21
|
0
|
|
|
|
|
|
buffer.resize(depth); |
22
|
0
|
|
|
|
|
|
} |
23
|
|
|
|
|
|
|
|
24
|
0
|
|
|
|
|
|
static panda::string humanize (const char* symbol) { |
25
|
0
|
0
|
|
|
|
|
std::regex re("(.+)\\((.+)\\+0x(.+)\\) \\[(.+)\\]"); |
26
|
0
|
|
|
|
|
|
std::cmatch what; |
27
|
0
|
0
|
|
|
|
|
if (regex_match(symbol, what, re)) { |
|
|
0
|
|
|
|
|
|
28
|
0
|
0
|
|
|
|
|
panda::string dll (what[1].first, what[1].length()); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
29
|
0
|
0
|
|
|
|
|
panda::string mangled_name (what[2].first, what[2].length()); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
30
|
0
|
0
|
|
|
|
|
panda::string symbol_offset (what[3].first, what[3].length()); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
31
|
0
|
0
|
|
|
|
|
panda::string address (what[4].first, what[4].length()); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
int status; |
34
|
0
|
0
|
|
|
|
|
char* demangled_name = abi::__cxa_demangle(mangled_name.c_str(), nullptr, 0, &status); |
|
|
0
|
|
|
|
|
|
35
|
0
|
0
|
|
|
|
|
if (demangled_name) { |
36
|
|
|
|
|
|
|
using guard_t = std::unique_ptr>; |
37
|
0
|
0
|
|
|
|
|
guard_t guard(&demangled_name, [](char** ptr) { free(*ptr); }); |
|
|
0
|
|
|
|
|
|
38
|
|
|
|
|
|
|
// mimic gdb style, i.e. |
39
|
|
|
|
|
|
|
// 0x00007ffff77c832c in Catch::TestInvokerAsFunction::invoke() const () from ../../var/lib/x86_64-linux/auto/Test/Catch/Catch.so |
40
|
0
|
0
|
|
|
|
|
return address + " in " + demangled_name + " from " + dll; |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
} |
43
|
0
|
0
|
|
|
|
|
return panda::string("[demangle failed]") + symbol; |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
0
|
|
|
|
|
|
string backtrace::get_trace_string () const { |
47
|
0
|
|
|
|
|
|
panda::string result = ""; |
48
|
|
|
|
|
|
|
using guard_t = std::unique_ptr>; |
49
|
0
|
|
|
|
|
|
char** symbols = backtrace_symbols(buffer.data(), buffer.size()); |
50
|
0
|
0
|
|
|
|
|
if (symbols) { |
51
|
0
|
0
|
|
|
|
|
guard_t guard(&symbols, [](char*** ptr) { free(*ptr); }); |
52
|
0
|
0
|
|
|
|
|
for (int i = 0; i < static_cast(buffer.size()); ++i) { |
53
|
0
|
0
|
|
|
|
|
result += humanize(symbols[i]) + "\n"; |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
} |
56
|
0
|
|
|
|
|
|
return result; |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
#else |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
backtrace::backtrace () noexcept {} |
62
|
|
|
|
|
|
|
string backtrace::get_trace_string () const { return {}; } |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
#endif |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
67
|
0
|
|
|
|
|
|
exception::exception () noexcept {} |
68
|
|
|
|
|
|
|
|
69
|
0
|
|
|
|
|
|
exception::exception (const string& whats) noexcept : _whats(whats) {} |
70
|
|
|
|
|
|
|
|
71
|
0
|
|
|
|
|
|
exception::exception (const exception& oth) noexcept : backtrace(oth), _whats(oth._whats) {} |
72
|
|
|
|
|
|
|
|
73
|
0
|
|
|
|
|
|
exception& exception::operator= (const exception& oth) noexcept { |
74
|
0
|
|
|
|
|
|
_whats = oth._whats; |
75
|
0
|
|
|
|
|
|
backtrace::operator=(oth); |
76
|
0
|
|
|
|
|
|
return *this; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
0
|
|
|
|
|
|
const char* exception::what () const noexcept { |
80
|
0
|
|
|
|
|
|
_whats = whats(); |
81
|
0
|
|
|
|
|
|
return _whats.c_str(); |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
0
|
|
|
|
|
|
string exception::whats () const noexcept { |
85
|
0
|
|
|
|
|
|
return _whats; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
} |