Skip to content

Commit

Permalink
Use Google demangler for stripped (short) symbols.
Browse files Browse the repository at this point in the history
This has two notable advantages over what we were doing
before:

1. it does a better job of stripping the extraneous information
   than my previous ad-hoc algorithm did.

2. it doesn't rely on shelling out to c++filt, so it's more
   portable and faster.
  • Loading branch information
haberman committed Nov 7, 2017
1 parent 1b6455f commit 82a228d
Show file tree
Hide file tree
Showing 5 changed files with 1,978 additions and 45 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ add_custom_command(

add_library(libbloaty
src/bloaty.cc
src/demangle.cc
src/disassemble.cc
${CMAKE_CURRENT_BINARY_DIR}/src/bloaty.pb.cc
src/dwarf.cc
Expand Down
65 changes: 24 additions & 41 deletions src/bloaty.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@

#include "bloaty.h"
#include "bloaty.pb.h"
#include "demangle.h"

using absl::string_view;

Expand Down Expand Up @@ -243,7 +244,7 @@ LineReader ReadLinesFromPipe(const std::string& cmd) {

// Demangler ///////////////////////////////////////////////////////////////////

Demangler::Demangler() {
void Demangler::Spawn() {
int toproc_pipe_fd[2];
int fromproc_pipe_fd[2];
if (pipe(toproc_pipe_fd) < 0 || pipe(fromproc_pipe_fd) < 0) {
Expand Down Expand Up @@ -290,47 +291,33 @@ Demangler::Demangler() {
}

Demangler::~Demangler() {
int status;
kill(child_pid_, SIGTERM);
waitpid(child_pid_, &status, WEXITED);
fclose(write_file_);
}

// C++ Symbol names can get really long because they include all the parameter
// types. For example:
//
// bloaty::RangeMap::ComputeRollup(std::vector<bloaty::RangeMap const*, std::allocator<bloaty::RangeMap const*> > const&, bloaty::Rollup*)
//
// This parameter info is often unnecessary. This class strips it. This will
// cause ambiguity in the case of overloaded functions, but the user can
// disambiguate with "cppsymbols".
//
// This transformation is, by its nature, heuristic and inexact. Improvements
// welcome.
absl::string_view Demangler::StripName(absl::string_view name) {
absl::ConsumeSuffix(&name, " const");

if (!name.empty() && name[name.size() - 1] != ')') {
// This doesn't look like a function.
return name;
if (write_file_) {
int status;
kill(child_pid_, SIGTERM);
waitpid(child_pid_, &status, WEXITED);
fclose(write_file_);
}
}

int nesting = 0;
for (size_t n = name.size() - 1; n < name.size(); --n) {
if (name[n] == '(') {
if (--nesting == 0) {
return name.substr(0, n);
}
} else if (name[n] == ')') {
++nesting;
std::string Demangler::Demangle(absl::string_view symbol, bool strip) {
if (strip) {
char buf[1024];
if (::Demangle(symbol.data(), buf, sizeof(buf))) {
return std::string(buf);
} else {
return std::string(symbol);
}
} else {
return DemangleWithCppFilt(symbol);
}

return name;
}

std::string Demangler::Demangle(const std::string& symbol, bool strip) {
const char *writeptr = symbol.c_str();
std::string Demangler::DemangleWithCppFilt(absl::string_view symbol) {
if (!write_file_) {
Spawn();
}

const char *writeptr = symbol.data();
const char *writeend = writeptr + symbol.size();

while (writeptr < writeend) {
Expand All @@ -351,11 +338,7 @@ std::string Demangler::Demangle(const std::string& symbol, bool strip) {
}

reader_->Next();
std::string ret = reader_->line();
if (strip) {
ret = std::string(StripName(ret));
}
return ret;
return reader_->line();
}


Expand Down
10 changes: 6 additions & 4 deletions src/bloaty.h
Original file line number Diff line number Diff line change
Expand Up @@ -326,18 +326,20 @@ LineReader ReadLinesFromPipe(const std::string& cmd);

class Demangler {
public:
Demangler();
Demangler() {}
~Demangler();

// If |strip| is true, we try to strip parameters and other extraneous info
// from the symbol.
std::string Demangle(const std::string& symbol, bool strip);
std::string Demangle(absl::string_view symbol, bool strip);

private:
BLOATY_DISALLOW_COPY_AND_ASSIGN(Demangler);

static absl::string_view StripName(absl::string_view);
FILE* write_file_;
void Spawn();
std::string DemangleWithCppFilt(absl::string_view symbol);

FILE* write_file_ = nullptr;
std::unique_ptr<LineReader> reader_;
pid_t child_pid_;
};
Expand Down
Loading

0 comments on commit 82a228d

Please sign in to comment.