]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common/BackTrace: add dump()
authorSage Weil <sage@redhat.com>
Fri, 15 Jun 2018 22:54:55 +0000 (17:54 -0500)
committerSage Weil <sage@redhat.com>
Sat, 16 Jun 2018 02:37:07 +0000 (21:37 -0500)
Signed-off-by: Sage Weil <sage@redhat.com>
src/common/BackTrace.cc
src/common/BackTrace.h

index c179d1dac125264a502ea943d7923cf3156b7a21..90b83df356c1cbdb37ad49bdef9c5138a9c9a5e3 100644 (file)
@@ -1,9 +1,13 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
 #include <ostream>
 #include <cxxabi.h>
 #include <string.h>
 
 #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();
+}
+
 }
index 372788e6b64e63a304dd5abb5292ff655e24b513..5cb73d47bd6c4cce893b2d90d09486c3e6658f81 100644 (file)
@@ -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) {