]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
7c673cae FG |
4 | #include <ostream> |
5 | #include <cxxabi.h> | |
7c673cae FG |
6 | #include <string.h> |
7 | ||
8 | #include "BackTrace.h" | |
7c673cae | 9 | #include "common/version.h" |
11fdf7f2 | 10 | #include "common/Formatter.h" |
7c673cae | 11 | |
7c673cae FG |
12 | namespace ceph { |
13 | ||
14 | void BackTrace::print(std::ostream& out) const | |
15 | { | |
16 | out << " " << pretty_version_to_str() << std::endl; | |
17 | for (size_t i = skip; i < size; i++) { | |
f67539c2 | 18 | out << " " << (i-skip+1) << ": " << demangle(strings[i]) << std::endl; |
7c673cae FG |
19 | } |
20 | } | |
21 | ||
11fdf7f2 TL |
22 | void BackTrace::dump(Formatter *f) const |
23 | { | |
24 | f->open_array_section("backtrace"); | |
25 | for (size_t i = skip; i < size; i++) { | |
26 | // out << " " << (i-skip+1) << ": " << strings[i] << std::endl; | |
f67539c2 TL |
27 | f->dump_string("frame", demangle(strings[i])); |
28 | } | |
29 | f->close_section(); | |
30 | } | |
11fdf7f2 | 31 | |
f67539c2 TL |
32 | std::string BackTrace::demangle(const char* name) |
33 | { | |
34 | // find the parentheses and address offset surrounding the mangled name | |
11fdf7f2 | 35 | #ifdef __FreeBSD__ |
f67539c2 | 36 | static constexpr char OPEN = '<'; |
11fdf7f2 | 37 | #else |
f67539c2 | 38 | static constexpr char OPEN = '('; |
11fdf7f2 | 39 | #endif |
f67539c2 TL |
40 | const char* begin = nullptr; |
41 | const char* end = nullptr; | |
42 | for (const char *j = name; *j; ++j) { | |
43 | if (*j == OPEN) { | |
44 | begin = j + 1; | |
45 | } else if (*j == '+') { | |
46 | end = j; | |
11fdf7f2 | 47 | } |
f67539c2 TL |
48 | } |
49 | if (begin && end && begin < end) { | |
50 | std::string mangled(begin, end); | |
51 | int status; | |
52 | // only demangle a C++ mangled name | |
53 | if (mangled.compare(0, 2, "_Z") == 0) { | |
54 | // let __cxa_demangle do the malloc | |
55 | char* demangled = abi::__cxa_demangle(mangled.c_str(), nullptr, nullptr, &status); | |
56 | if (!status) { | |
57 | std::string full_name{OPEN}; | |
58 | full_name += demangled; | |
59 | full_name += end; | |
60 | // buf could be reallocated, so free(demangled) instead | |
61 | free(demangled); | |
62 | return full_name; | |
11fdf7f2 | 63 | } |
f67539c2 | 64 | // demangle failed, just pretend it's a C function with no args |
11fdf7f2 | 65 | } |
f67539c2 TL |
66 | // C function |
67 | return mangled + "()"; | |
68 | } else { | |
69 | // didn't find the mangled name, just print the whole line | |
70 | return name; | |
11fdf7f2 | 71 | } |
11fdf7f2 TL |
72 | } |
73 | ||
7c673cae | 74 | } |