]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/BackTrace.cc
import ceph 16.2.7
[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 11
7c673cae
FG
12namespace ceph {
13
14void 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
22void 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
32std::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}