]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/BackTrace.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / common / BackTrace.cc
CommitLineData
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
FG
11
12#define _STR(x) #x
13#define STRINGIFY(x) _STR(x)
14
15namespace ceph {
16
17void BackTrace::print(std::ostream& out) const
18{
19 out << " " << pretty_version_to_str() << std::endl;
20 for (size_t i = skip; i < size; i++) {
21 // out << " " << (i-skip+1) << ": " << strings[i] << std::endl;
22
23 size_t sz = 1024; // just a guess, template names will go much wider
24 char *function = (char *)malloc(sz);
25 if (!function)
26 return;
27 char *begin = 0, *end = 0;
28
29 // find the parentheses and address offset surrounding the mangled name
30#ifdef __FreeBSD__
31 static constexpr char OPEN = '<';
32#else
33 static constexpr char OPEN = '(';
34#endif
35 for (char *j = strings[i]; *j; ++j) {
36 if (*j == OPEN)
37 begin = j+1;
38 else if (*j == '+')
39 end = j;
40 }
41 if (begin && end) {
42 int len = end - begin;
43 char *foo = (char *)malloc(len+1);
44 if (!foo) {
45 free(function);
46 return;
47 }
48 memcpy(foo, begin, len);
49 foo[len] = 0;
50
51 int status;
52 char *ret = nullptr;
53 // only demangle a C++ mangled name
54 if (foo[0] == '_' && foo[1] == 'Z')
55 ret = abi::__cxa_demangle(foo, function, &sz, &status);
56 if (ret) {
57 // return value may be a realloc() of the input
58 function = ret;
59 }
60 else {
61 // demangling failed, just pretend it's a C function with no args
62 strncpy(function, foo, sz);
63 strncat(function, "()", sz);
64 function[sz-1] = 0;
65 }
66 out << " " << (i-skip+1) << ": " << OPEN << function << end << std::endl;
67 //fprintf(out, " %s:%s\n", stack.strings[i], function);
68 free(foo);
69 } else {
70 // didn't find the mangled name, just print the whole line
71 out << " " << (i-skip+1) << ": " << strings[i] << std::endl;
72 }
73 free(function);
74 }
75}
76
11fdf7f2
TL
77void BackTrace::dump(Formatter *f) const
78{
79 f->open_array_section("backtrace");
80 for (size_t i = skip; i < size; i++) {
81 // out << " " << (i-skip+1) << ": " << strings[i] << std::endl;
82
83 size_t sz = 1024; // just a guess, template names will go much wider
84 char *function = (char *)malloc(sz);
85 if (!function)
86 return;
87 char *begin = 0, *end = 0;
88
89 // find the parentheses and address offset surrounding the mangled name
90#ifdef __FreeBSD__
91 static constexpr char OPEN = '<';
92#else
93 static constexpr char OPEN = '(';
94#endif
95 for (char *j = strings[i]; *j; ++j) {
96 if (*j == OPEN)
97 begin = j+1;
98 else if (*j == '+')
99 end = j;
100 }
101 if (begin && end) {
102 int len = end - begin;
103 char *foo = (char *)malloc(len+1);
104 if (!foo) {
105 free(function);
106 return;
107 }
108 memcpy(foo, begin, len);
109 foo[len] = 0;
110
111 int status;
112 char *ret = nullptr;
113 // only demangle a C++ mangled name
114 if (foo[0] == '_' && foo[1] == 'Z')
115 ret = abi::__cxa_demangle(foo, function, &sz, &status);
116 if (ret) {
117 // return value may be a realloc() of the input
118 function = ret;
119 }
120 else {
121 // demangling failed, just pretend it's a C function with no args
122 strncpy(function, foo, sz);
123 strncat(function, "()", sz);
124 function[sz-1] = 0;
125 }
126 f->dump_stream("frame") << OPEN << function << end;
127 //fprintf(out, " %s:%s\n", stack.strings[i], function);
128 free(foo);
129 } else {
130 // didn't find the mangled name, just print the whole line
131 //out << " " << (i-skip+1) << ": " << strings[i] << std::endl;
132 f->dump_string("frame", strings[i]);
133 }
134 free(function);
135 }
136 f->close_section();
137}
138
7c673cae 139}