Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / common / BackTrace.cc
1 #include <ostream>
2 #include <cxxabi.h>
3 #include <string.h>
4
5 #include "BackTrace.h"
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 }