]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/BackTrace.cc
update sources to v12.1.0
[ceph.git] / ceph / src / common / BackTrace.cc
CommitLineData
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
11namespace ceph {
12
13void 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}