Skip to contentSkip to conversation

perf tool: add Rust demangling

PATCH New David Tolnay 2 participants 2 messages Jul 9, 2016 – Jul 13, 2016 perf events

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 perf tool: add Rust demangling

From: David Tolnay <[email protected]>
Date: Sat, 9 Jul 2016 00:20:00 -0700
Subject: [PATCH] perf tool: add Rust demangling

Rust demangling is another step after bfd demangling. Add a diagnosis to identify mangled Rust symbols based on the hash that the Rust mangler appends as the last path component, as well as other characteristics. Add a demangler to reconstruct the original symbol.

---
 tools/perf/util/Build           |   1 +
 tools/perf/util/demangle-rust.c | 269 ++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/demangle-rust.h |   7 ++
 tools/perf/util/symbol-elf.c    |   8 ++
 4 files changed, 285 insertions(+)
 create mode 100644 tools/perf/util/demangle-rust.c
 create mode 100644 tools/perf/util/demangle-rust.h
tools/perf/util/Build +1 -0
index 8c6c8a0..16b59b5 100644
@@ -108,6 +108,7 @@ libperf-y += scripting-engines/
 libperf-$(CONFIG_ZLIB) += zlib.o
 libperf-$(CONFIG_LZMA) += lzma.o
 libperf-y += demangle-java.o
+libperf-y += demangle-rust.o
 
 ifdef CONFIG_JITDUMP
 libperf-$(CONFIG_LIBELF) += jitdump.o
tools/perf/util/demangle-rust.c new file +269 -0

269 lines not on this page · raw message

tools/perf/util/demangle-rust.h new file +7 -0
new file mode 100644
index 0000000..7b41ead
@@ -0,0 +1,7 @@
+#ifndef __PERF_DEMANGLE_RUST
+#define __PERF_DEMANGLE_RUST 1
+
+bool rust_is_mangled(const char *str);
+void rust_demangle_sym(char *str);
+
+#endif /* __PERF_DEMANGLE_RUST */
tools/perf/util/symbol-elf.c +8 -0
index 87a297d..5f345d6 100644
@@ -7,6 +7,7 @@
 
 #include "symbol.h"
 #include "demangle-java.h"
+#include "demangle-rust.h"
 #include "machine.h"
 #include "vdso.h"
 #include <symbol/kallsyms.h>
@@ -1072,6 +1073,13 @@ new_symbol:
 			demangled = bfd_demangle(NULL, elf_name, demangle_flags);
 			if (demangled == NULL)
 				demangled = java_demangle_sym(elf_name, JAVA_DEMANGLE_NORET);
+			else if (rust_is_mangled(demangled))
+				/*
+				 * Input to Rust demangling is the BFD-demangled
+				 * name which it Rust-demangles in place.
+				 */
+				rust_demangle_sym(demangled);
+
 			if (demangled != NULL)
 				elf_name = demangled;
 		}
Signature · 1 line
2.9.0
#1 lore raw

[tip:perf/core] perf symbols: Add Rust demangling

perf symbols: Add Rust demangling
Commit-ID:  cae15db74999edb96dd9f5bbd4d55849391dd92b
Gitweb:     http://git.kernel.org/tip/cae15db74999edb96dd9f5bbd4d55849391dd92b
Author:     David Tolnay <[email protected]>
AuthorDate: Sat, 9 Jul 2016 00:20:00 -0700
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Tue, 12 Jul 2016 16:12:38 -0300

perf symbols: Add Rust demangling

Rust demangling is another step after bfd demangling. Add a diagnosis to identify mangled Rust symbols based on the hash that the Rust mangler appends as the last path component, as well as other characteristics. Add a demangler to reconstruct the original symbol.

Committer notes:

How I tested it:

Enabled COPR on Fedora 24 and then installed the 'rust-binary' package, with it:

  $ cat src/main.rs
  fn main() {
      println!("Hello, world!");
  }
  $ cat Cargo.toml
  [package]

name = "hello_world"
version = "0.0.1"
authors = [ "Arnaldo Carvalho de Melo <[email protected]>" ]

  $ perf record cargo bench
   Compiling hello_world v0.0.1 (file:///home/acme/projects/hello_world)
     Running target/release/hello_world-d4b9dab4b2a47d75

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.096 MB perf.data (1457 samples) ] $

Before this patch:

  $ perf report --stdio --dsos librbml-e8edd0fd.so
  # dso: librbml-e8edd0fd.so
  #
  # Total Lost Samples: 0
  #
  # Samples: 1K of event 'cycles:u'
  # Event count (approx.): 979599126
  #
  # Overhead  Command  Symbol
  # ........  .......  .............................................................................................................
  #
       1.78%  rustc    [.] rbml::reader::maybe_get_doc::hb9d387df6024b15b
       1.50%  rustc    [.] _$LT$reader..DocsIterator$LT$$u27$a$GT$$u20$as$u20$std..iter..Iterator$GT$::next::hd9af9e60d79a35c8
       1.20%  rustc    [.] rbml::reader::doc_at::hc88107fba445af31
       0.46%  rustc    [.] _$LT$reader..TaggedDocsIterator$LT$$u27$a$GT$$u20$as$u20$std..iter..Iterator$GT$::next::h0cb40e696e4bb489
       0.35%  rustc    [.] rbml::reader::Decoder::_next_int::h66eef7825a398bc3
       0.29%  rustc    [.] rbml::reader::Decoder::_next_sub::h8e5266005580b836
       0.15%  rustc    [.] rbml::reader::get_doc::h094521c645459139
       0.14%  rustc    [.] _$LT$reader..Decoder$LT$$u27$doc$GT$$u20$as$u20$serialize..Decoder$GT$::read_u32::h0acea2fff9669327
       0.07%  rustc    [.] rbml::reader::Decoder::next_doc::h6714d469c9dfaf91
       0.07%  rustc    [.] _ZN4rbml6reader10doc_as_u6417h930b740aa94f1d3aE@plt
       0.06%  rustc    [.] _fini
  $

After:

  $ perf report --stdio --dsos librbml-e8edd0fd.so
  # dso: librbml-e8edd0fd.so
  #
  # Total Lost Samples: 0
  #
  # Samples: 1K of event 'cycles:u'
  # Event count (approx.): 979599126
  #
  # Overhead  Command  Symbol
  # ........  .......  .................................................................
  #
     1.78%  rustc    [.] rbml::reader::maybe_get_doc
     1.50%  rustc    [.] <reader::DocsIterator<'a> as std::iter::Iterator>::next
     1.20%  rustc    [.] rbml::reader::doc_at
     0.46%  rustc    [.] <reader::TaggedDocsIterator<'a> as std::iter::Iterator>::next
     0.35%  rustc    [.] rbml::reader::Decoder::_next_int
     0.29%  rustc    [.] rbml::reader::Decoder::_next_sub
     0.15%  rustc    [.] rbml::reader::get_doc
     0.14%  rustc    [.] <reader::Decoder<'doc> as serialize::Decoder>::read_u32
     0.07%  rustc    [.] rbml::reader::Decoder::next_doc
     0.07%  rustc    [.] _ZN4rbml6reader10doc_as_u6417h930b740aa94f1d3aE@plt
     0.06%  rustc    [.] _fini
  $
---
 tools/perf/util/Build           |   1 +
 tools/perf/util/demangle-rust.c | 269 ++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/demangle-rust.h |   7 ++
 tools/perf/util/symbol-elf.c    |   8 ++
 4 files changed, 285 insertions(+)
tools/perf/util/Build +1 -0
index eda68f5..2fa7d8b 100644
@@ -113,6 +113,7 @@ libperf-y += scripting-engines/
 libperf-$(CONFIG_ZLIB) += zlib.o
 libperf-$(CONFIG_LZMA) += lzma.o
 libperf-y += demangle-java.o
+libperf-y += demangle-rust.o
 
 ifdef CONFIG_JITDUMP
 libperf-$(CONFIG_LIBELF) += jitdump.o
tools/perf/util/demangle-rust.c new file +269 -0

269 lines not on this page · raw message

tools/perf/util/demangle-rust.h new file +7 -0
new file mode 100644
index 0000000..7b41ead
@@ -0,0 +1,7 @@
+#ifndef __PERF_DEMANGLE_RUST
+#define __PERF_DEMANGLE_RUST 1
+
+bool rust_is_mangled(const char *str);
+void rust_demangle_sym(char *str);
+
+#endif /* __PERF_DEMANGLE_RUST */
tools/perf/util/symbol-elf.c +8 -0
index cebf98e..a34321e 100644
@@ -7,6 +7,7 @@
 
 #include "symbol.h"
 #include "demangle-java.h"
+#include "demangle-rust.h"
 #include "machine.h"
 #include "vdso.h"
 #include <symbol/kallsyms.h>
@@ -1081,6 +1082,13 @@ new_symbol:
 			demangled = bfd_demangle(NULL, elf_name, demangle_flags);
 			if (demangled == NULL)
 				demangled = java_demangle_sym(elf_name, JAVA_DEMANGLE_NORET);
+			else if (rust_is_mangled(demangled))
+				/*
+				 * Input to Rust demangling is the BFD-demangled
+				 * name which it Rust-demangles in place.
+				 */
+				rust_demangle_sym(demangled);
+
 			if (demangled != NULL)
 				elf_name = demangled;
 		}