From: Sage Weil Date: Fri, 15 Jun 2018 22:54:55 +0000 (-0500) Subject: common/BackTrace: add dump() X-Git-Tag: v14.0.1~1042^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4998b5b584ac57d67ca5ba28d3ec3a3e4fe4486f;p=ceph.git common/BackTrace: add dump() Signed-off-by: Sage Weil --- diff --git a/src/common/BackTrace.cc b/src/common/BackTrace.cc index c179d1dac125..90b83df356c1 100644 --- a/src/common/BackTrace.cc +++ b/src/common/BackTrace.cc @@ -1,9 +1,13 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + #include #include #include #include "BackTrace.h" #include "common/version.h" +#include "common/Formatter.h" #define _STR(x) #x #define STRINGIFY(x) _STR(x) @@ -70,4 +74,66 @@ void BackTrace::print(std::ostream& out) const } } +void BackTrace::dump(Formatter *f) const +{ + f->open_array_section("backtrace"); + for (size_t i = skip; i < size; i++) { + // out << " " << (i-skip+1) << ": " << strings[i] << std::endl; + + size_t sz = 1024; // just a guess, template names will go much wider + char *function = (char *)malloc(sz); + if (!function) + return; + char *begin = 0, *end = 0; + + // find the parentheses and address offset surrounding the mangled name +#ifdef __FreeBSD__ + static constexpr char OPEN = '<'; +#else + static constexpr char OPEN = '('; +#endif + for (char *j = strings[i]; *j; ++j) { + if (*j == OPEN) + begin = j+1; + else if (*j == '+') + end = j; + } + if (begin && end) { + int len = end - begin; + char *foo = (char *)malloc(len+1); + if (!foo) { + free(function); + return; + } + memcpy(foo, begin, len); + foo[len] = 0; + + int status; + char *ret = nullptr; + // only demangle a C++ mangled name + if (foo[0] == '_' && foo[1] == 'Z') + ret = abi::__cxa_demangle(foo, function, &sz, &status); + if (ret) { + // return value may be a realloc() of the input + function = ret; + } + else { + // demangling failed, just pretend it's a C function with no args + strncpy(function, foo, sz); + strncat(function, "()", sz); + function[sz-1] = 0; + } + f->dump_stream("frame") << OPEN << function << end; + //fprintf(out, " %s:%s\n", stack.strings[i], function); + free(foo); + } else { + // didn't find the mangled name, just print the whole line + //out << " " << (i-skip+1) << ": " << strings[i] << std::endl; + f->dump_string("frame", strings[i]); + } + free(function); + } + f->close_section(); +} + } diff --git a/src/common/BackTrace.h b/src/common/BackTrace.h index 372788e6b64e..5cb73d47bd6c 100644 --- a/src/common/BackTrace.h +++ b/src/common/BackTrace.h @@ -1,3 +1,6 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + #ifndef CEPH_BACKTRACE_H #define CEPH_BACKTRACE_H @@ -10,6 +13,8 @@ namespace ceph { +class Formatter; + struct BackTrace { const static int max = 100; @@ -36,6 +41,7 @@ struct BackTrace { const BackTrace& operator=(const BackTrace& other); void print(std::ostream& out) const; + void dump(Formatter *f) const; }; inline std::ostream& operator<<(std::ostream& out, const BackTrace& bt) {