]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #include <ostream> |
2 | #include <cxxabi.h> | |
7c673cae FG |
3 | #include <string.h> |
4 | ||
5 | #include "BackTrace.h" | |
7c673cae FG |
6 | #include "common/version.h" |
7 | ||
8 | #define _STR(x) #x | |
9 | #define STRINGIFY(x) _STR(x) | |
10 | ||
11 | namespace ceph { | |
12 | ||
13 | void BackTrace::print(std::ostream& out) const | |
14 | { | |
15 | out << " " << pretty_version_to_str() << std::endl; | |
16 | for (size_t i = skip; i < size; i++) { | |
17 | // out << " " << (i-skip+1) << ": " << strings[i] << std::endl; | |
18 | ||
19 | size_t sz = 1024; // just a guess, template names will go much wider | |
20 | char *function = (char *)malloc(sz); | |
21 | if (!function) | |
22 | return; | |
23 | char *begin = 0, *end = 0; | |
24 | ||
25 | // find the parentheses and address offset surrounding the mangled name | |
26 | #ifdef __FreeBSD__ | |
27 | static constexpr char OPEN = '<'; | |
28 | #else | |
29 | static constexpr char OPEN = '('; | |
30 | #endif | |
31 | for (char *j = strings[i]; *j; ++j) { | |
32 | if (*j == OPEN) | |
33 | begin = j+1; | |
34 | else if (*j == '+') | |
35 | end = j; | |
36 | } | |
37 | if (begin && end) { | |
38 | int len = end - begin; | |
39 | char *foo = (char *)malloc(len+1); | |
40 | if (!foo) { | |
41 | free(function); | |
42 | return; | |
43 | } | |
44 | memcpy(foo, begin, len); | |
45 | foo[len] = 0; | |
46 | ||
47 | int status; | |
48 | char *ret = nullptr; | |
49 | // only demangle a C++ mangled name | |
50 | if (foo[0] == '_' && foo[1] == 'Z') | |
51 | ret = abi::__cxa_demangle(foo, function, &sz, &status); | |
52 | if (ret) { | |
53 | // return value may be a realloc() of the input | |
54 | function = ret; | |
55 | } | |
56 | else { | |
57 | // demangling failed, just pretend it's a C function with no args | |
58 | strncpy(function, foo, sz); | |
59 | strncat(function, "()", sz); | |
60 | function[sz-1] = 0; | |
61 | } | |
62 | out << " " << (i-skip+1) << ": " << OPEN << function << end << std::endl; | |
63 | //fprintf(out, " %s:%s\n", stack.strings[i], function); | |
64 | free(foo); | |
65 | } else { | |
66 | // didn't find the mangled name, just print the whole line | |
67 | out << " " << (i-skip+1) << ": " << strings[i] << std::endl; | |
68 | } | |
69 | free(function); | |
70 | } | |
71 | } | |
72 | ||
73 | } |