From: Kefu Chai Date: Tue, 8 Sep 2020 11:52:46 +0000 (+0800) Subject: common/BackTrace: extract demangle() out X-Git-Tag: v16.1.0~1075^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ea6abcf34c11c80dec507f7dee8babd26440196c;p=ceph.git common/BackTrace: extract demangle() out so it can be reused by crimson Signed-off-by: Kefu Chai --- diff --git a/src/common/BackTrace.cc b/src/common/BackTrace.cc index 5e014946982d..453ba02dbb9d 100644 --- a/src/common/BackTrace.cc +++ b/src/common/BackTrace.cc @@ -15,59 +15,7 @@ void BackTrace::print(std::ostream& out) const { out << " " << pretty_version_to_str() << std::endl; 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; - } - out << " " << (i-skip+1) << ": " << OPEN << function << end << std::endl; - //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; - } - free(function); + out << " " << (i-skip+1) << ": " << demangle(strings[i]) << std::endl; } } @@ -76,61 +24,57 @@ 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; + f->dump_string("frame", demangle(strings[i])); + } + f->close_section(); +} - 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 +std::string BackTrace::demangle(const char* name) +{ + // find the parentheses and address offset surrounding the mangled name #ifdef __FreeBSD__ - static constexpr char OPEN = '<'; + static constexpr char OPEN = '<'; #else - static constexpr char OPEN = '('; + static constexpr char OPEN = '('; #endif - for (char *j = strings[i]; *j; ++j) { - if (*j == OPEN) - begin = j+1; - else if (*j == '+') - end = j; + const char* begin = nullptr; + const char* end = nullptr; + for (const char *j = name; *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; + } + if (begin && end) { + std::string mangled(begin, end); + int status; + // only demangle a C++ mangled name + if (mangled.compare(0, 2, "_Z") == 0) { + // just a guess, template names will go much wider + size_t len = 1024; + char* buf = (char*)malloc(len); + if (!buf) { + return {}; } - else { - // demangling failed, just pretend it's a C function with no args - strncpy(function, foo, sz); - strncat(function, "()", sz); - function[sz-1] = 0; + if (char* demangled = abi::__cxa_demangle(mangled.c_str(), buf, &len, &status)) { + std::string full_name{OPEN}; + full_name += demangled; + full_name += end; + // buf could be reallocated, so free(demangled) instead + free(demangled); + return full_name; + } else { + // demangle failed, just pretend it's a C function with no args + free(buf); } - 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); + // C function + return mangled + "()"; + } else { + // didn't find the mangled name, just print the whole line + return name; } - f->close_section(); } } diff --git a/src/common/BackTrace.h b/src/common/BackTrace.h index 5cb73d47bd6c..0132fa5da877 100644 --- a/src/common/BackTrace.h +++ b/src/common/BackTrace.h @@ -42,6 +42,7 @@ struct BackTrace { void print(std::ostream& out) const; void dump(Formatter *f) const; + static std::string demangle(const char* name); }; inline std::ostream& operator<<(std::ostream& out, const BackTrace& bt) {