From 3e3eb3e2b61f2cba293faa785b83bc340c439ed4 Mon Sep 17 00:00:00 2001 From: Jason Rodney Hansen Date: Wed, 13 Mar 2019 11:56:54 -0600 Subject: [PATCH 1/6] Add demangle option to collapsers --- Cargo.toml | 2 + src/bin/collapse-dtrace.rs | 5 + src/bin/collapse-perf.rs | 5 + src/collapse/dtrace.rs | 21 +++- src/collapse/perf.rs | 11 +++ tests/collapse-dtrace.rs | 23 ++++- tests/collapse-guess.rs | 6 +- tests/collapse-perf.rs | 36 ++++++- tests/collapse_common/mod.rs | 12 ++- tests/data/collapse-dtrace/mangled.txt | 94 ++++++++++++++++++ .../collapse-dtrace/results/demangled.txt | 4 + tests/data/collapse-perf/mangled.txt | 99 +++++++++++++++++++ .../data/collapse-perf/results/demangled.txt | 4 + 13 files changed, 305 insertions(+), 17 deletions(-) create mode 100644 tests/data/collapse-dtrace/mangled.txt create mode 100644 tests/data/collapse-dtrace/results/demangled.txt create mode 100644 tests/data/collapse-perf/mangled.txt create mode 100644 tests/data/collapse-perf/results/demangled.txt diff --git a/Cargo.toml b/Cargo.toml index 8ef3d2d2..fa81aa4b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,8 @@ lazy_static = "1.3.0" fnv = "1.0.3" itoa = "0.4.3" indexmap = "1.0" +symbolic-common = "6.1.3" +symbolic-demangle = "6.1.3" [dev-dependencies] pretty_assertions = "0.6" diff --git a/src/bin/collapse-dtrace.rs b/src/bin/collapse-dtrace.rs index 7699e094..e8f8843e 100644 --- a/src/bin/collapse-dtrace.rs +++ b/src/bin/collapse-dtrace.rs @@ -30,6 +30,10 @@ struct Opt { #[structopt(long = "includeoffset")] includeoffset: bool, + /// Demangle function names + #[structopt(long = "demangle")] + demangle: bool, + /// perf script output file, or STDIN if not specified infile: Option, } @@ -40,6 +44,7 @@ impl Opt { self.infile, Options { includeoffset: self.includeoffset, + demangle: self.demangle, }, ) } diff --git a/src/bin/collapse-perf.rs b/src/bin/collapse-perf.rs index 881cf971..5d35b8a8 100644 --- a/src/bin/collapse-perf.rs +++ b/src/bin/collapse-perf.rs @@ -54,6 +54,10 @@ struct Opt { #[structopt(short = "v", long = "verbose", parse(from_occurrences))] verbose: usize, + /// Demangle function names + #[structopt(long = "demangle")] + demangle: bool, + /// perf script output file, or STDIN if not specified infile: Option, } @@ -69,6 +73,7 @@ impl Opt { annotate_jit: self.annotate_jit || self.annotate_all, annotate_kernel: self.annotate_kernel || self.annotate_all, event_filter: self.event_filter, + demangle: self.demangle, }, ) } diff --git a/src/collapse/dtrace.rs b/src/collapse/dtrace.rs index 2a553ff7..32fa912a 100644 --- a/src/collapse/dtrace.rs +++ b/src/collapse/dtrace.rs @@ -1,9 +1,11 @@ use super::Collapse; use fnv::FnvHashMap; use log::warn; +use std::borrow::Cow; use std::collections::VecDeque; use std::io; use std::io::prelude::*; +use symbolic_demangle::demangle; /// Settings that change how frames are named from the incoming stack traces. /// @@ -12,6 +14,9 @@ use std::io::prelude::*; pub struct Options { /// include function offset (except leafs) pub includeoffset: bool, + + /// Demangle function names + pub demangle: bool, } /// A stack collapser for the output of dtrace `ustrace()`. @@ -182,8 +187,17 @@ impl Folder { frame = Self::uncpp(frame); } - if frame.is_empty() { - frame = "-"; + let frame = if frame.is_empty() { + Cow::Owned("-".to_owned()) + } else if self.opt.demangle { + let mut parts = frame.split('`'); + if let (Some(pname), Some(func)) = (parts.next(), parts.next()) { + Cow::Owned(format!("{}`{}", pname, demangle(func))) + } else { + Cow::Borrowed(frame) + } + } else { + Cow::Borrowed(frame) }; if has_inlines { @@ -207,7 +221,7 @@ impl Folder { } else if has_semicolon { self.stack.push_front(frame.replace(';', ":")) } else { - self.stack.push_front(frame.to_owned()) + self.stack.push_front(frame.to_string()) } } @@ -231,6 +245,7 @@ impl Folder { stack_str.push_str(&e); } } + // count it! *self.occurrences.entry(stack_str).or_insert(0) += count; // reset for the next event diff --git a/src/collapse/perf.rs b/src/collapse/perf.rs index a8d73309..b0809e3b 100644 --- a/src/collapse/perf.rs +++ b/src/collapse/perf.rs @@ -1,9 +1,11 @@ use super::Collapse; use fnv::FnvHashMap; use log::warn; +use std::borrow::Cow; use std::collections::VecDeque; use std::io; use std::io::prelude::*; +use symbolic_demangle::demangle; const TIDY_GENERIC: bool = true; const TIDY_JAVA: bool = true; @@ -32,6 +34,9 @@ pub struct Options { /// Annotate kernel functions with a `_[k]` suffix. pub annotate_kernel: bool, + /// Demangle function names + pub demangle: bool, + /// Only consider samples of the given event type (see `perf list`). /// /// If this option is set to `None`, it will be set to the first encountered event type. @@ -318,6 +323,12 @@ impl Folder { return; } + let rawfunc = if self.opt.demangle { + demangle(rawfunc) + } else { + Cow::Borrowed(rawfunc) + }; + // Support Java inlining by splitting on "->". After the first func, the // rest are annotated with "_[i]" to mark them as inlined. // See https://github.com/brendangregg/FlameGraph/pull/89. diff --git a/tests/collapse-dtrace.rs b/tests/collapse-dtrace.rs index ada178ee..7c97e2e8 100644 --- a/tests/collapse-dtrace.rs +++ b/tests/collapse-dtrace.rs @@ -10,7 +10,7 @@ use std::io::{self, BufReader, Cursor}; use std::process::{Command, Stdio}; fn test_collapse_dtrace(test_file: &str, expected_file: &str, options: Options) -> io::Result<()> { - test_collapse(Folder::from(options), test_file, expected_file) + test_collapse(Folder::from(options), test_file, expected_file, false) } fn test_collapse_dtrace_logs(input_file: &str, asserter: F) @@ -43,6 +43,7 @@ fn collapse_dtrace_compare_to_upstream_with_offsets() { result_file, Options { includeoffset: true, + demangle: false, }, ) .unwrap() @@ -76,6 +77,7 @@ fn collapse_dtrace_compare_to_flamegraph_bug() { result_file, Options { includeoffset: true, + demangle: false, }, ) .unwrap() @@ -108,6 +110,21 @@ fn collapse_dtrace_scope_with_no_argument_list() { test_collapse_dtrace(test_file, result_file, Options::default()).unwrap() } +#[test] +fn collapse_dtrace_demangle() { + let test_file = "./tests/data/collapse-dtrace/mangled.txt"; + let result_file = "./tests/data/collapse-dtrace/results/demangled.txt"; + test_collapse_dtrace( + test_file, + result_file, + Options { + includeoffset: false, + demangle: true, + }, + ) + .unwrap() +} + #[test] fn collapse_dtrace_cli() { let input_file = "./flamegraph/example-dtrace-stacks.txt"; @@ -120,7 +137,7 @@ fn collapse_dtrace_cli() { .output() .expect("failed to execute process"); let expected = BufReader::new(File::open(expected_file).unwrap()); - compare_results(Cursor::new(output.stdout), expected, expected_file); + compare_results(Cursor::new(output.stdout), expected, expected_file, false); // Test with STDIN let mut child = Command::cargo_bin("inferno-collapse-dtrace") @@ -134,5 +151,5 @@ fn collapse_dtrace_cli() { io::copy(&mut input, stdin).unwrap(); let output = child.wait_with_output().expect("Failed to read stdout"); let expected = BufReader::new(File::open(expected_file).unwrap()); - compare_results(Cursor::new(output.stdout), expected, expected_file); + compare_results(Cursor::new(output.stdout), expected, expected_file, false); } diff --git a/tests/collapse-guess.rs b/tests/collapse-guess.rs index 0f9ab098..7b593b82 100644 --- a/tests/collapse-guess.rs +++ b/tests/collapse-guess.rs @@ -10,7 +10,7 @@ use std::io::{self, BufReader, Cursor}; use std::process::{Command, Stdio}; fn test_collapse_guess(test_file: &str, expected_file: &str) -> io::Result<()> { - test_collapse(Folder {}, test_file, expected_file) + test_collapse(Folder {}, test_file, expected_file, true) } fn test_collapse_guess_logs(input_file: &str, asserter: F) @@ -116,7 +116,7 @@ fn collapse_guess_cli() { .output() .expect("failed to execute process"); let expected = BufReader::new(File::open(expected_file).unwrap()); - compare_results(Cursor::new(output.stdout), expected, expected_file); + compare_results(Cursor::new(output.stdout), expected, expected_file, true); // Test with STDIN let mut child = Command::cargo_bin("inferno-collapse-guess") @@ -130,5 +130,5 @@ fn collapse_guess_cli() { io::copy(&mut input, stdin).unwrap(); let output = child.wait_with_output().expect("Failed to read stdout"); let expected = BufReader::new(File::open(expected_file).unwrap()); - compare_results(Cursor::new(output.stdout), expected, expected_file); + compare_results(Cursor::new(output.stdout), expected, expected_file, true); } diff --git a/tests/collapse-perf.rs b/tests/collapse-perf.rs index ae852ded..e516aa70 100644 --- a/tests/collapse-perf.rs +++ b/tests/collapse-perf.rs @@ -10,8 +10,18 @@ use std::io::{self, BufReader, Cursor}; use std::path::Path; use std::process::{Command, Stdio}; -fn test_collapse_perf(test_file: &str, expected_file: &str, options: Options) -> io::Result<()> { - test_collapse(Folder::from(options), test_file, expected_file) +fn test_collapse_perf( + test_file: &str, + expected_file: &str, + options: Options, + strip_quotes: bool, +) -> io::Result<()> { + test_collapse( + Folder::from(options), + test_file, + expected_file, + strip_quotes, + ) } fn test_collapse_perf_logs(input_file: &str, asserter: F) @@ -87,6 +97,7 @@ macro_rules! collapse_perf_tests_inner { test_path.join(test_file).to_str().unwrap(), results_path.join(result_file).to_str().unwrap(), options_from_vec(options), + true ) .unwrap() @@ -211,6 +222,7 @@ fn collapse_perf_example_perf_stacks() { "./flamegraph/example-perf-stacks.txt.gz", "./tests/data/collapse-perf/results/example-perf-stacks-collapsed.txt", Default::default(), + false, ) .unwrap(); } @@ -255,6 +267,22 @@ fn collapse_perf_should_warn_about_weird_input_lines() { ); } +#[test] +fn collapse_perf_demangle() { + let test_file = "./tests/data/collapse-perf/mangled.txt"; + let result_file = "./tests/data/collapse-perf/results/demangled.txt"; + test_collapse_perf( + test_file, + result_file, + Options { + demangle: true, + ..Default::default() + }, + false, + ) + .unwrap() +} + #[test] fn collapse_perf_cli() { let input_file = "./flamegraph/test/perf-vertx-stacks-01.txt"; @@ -268,7 +296,7 @@ fn collapse_perf_cli() { .output() .expect("failed to execute process"); let expected = BufReader::new(File::open(expected_file).unwrap()); - compare_results(Cursor::new(output.stdout), expected, expected_file); + compare_results(Cursor::new(output.stdout), expected, expected_file, true); // Test with STDIN let mut child = Command::cargo_bin("inferno-collapse-perf") @@ -283,5 +311,5 @@ fn collapse_perf_cli() { io::copy(&mut input, stdin).unwrap(); let output = child.wait_with_output().expect("Failed to read stdout"); let expected = BufReader::new(File::open(expected_file).unwrap()); - compare_results(Cursor::new(output.stdout), expected, expected_file); + compare_results(Cursor::new(output.stdout), expected, expected_file, true); } diff --git a/tests/collapse_common/mod.rs b/tests/collapse_common/mod.rs index 2d98865b..80b1297e 100644 --- a/tests/collapse_common/mod.rs +++ b/tests/collapse_common/mod.rs @@ -7,6 +7,7 @@ pub(crate) fn test_collapse( mut collapser: C, test_filename: &str, expected_filename: &str, + strip_quotes: bool, ) -> io::Result<()> where C: Collapse, @@ -53,7 +54,7 @@ where eprintln!("test output in {}", tm.display()); } // and then compare - compare_results(result, expected, expected_filename); + compare_results(result, expected, expected_filename, strip_quotes); Ok(return_value) } @@ -68,7 +69,7 @@ where testing_logger::validate(asserter); } -pub(crate) fn compare_results(result: R, mut expected: E, expected_file: &str) +pub(crate) fn compare_results(result: R, mut expected: E, expected_file: &str, strip_quotes: bool) where R: BufRead, E: BufRead, @@ -76,8 +77,11 @@ where let mut buf = String::new(); let mut line_num = 1; for line in result.lines() { - // Strip out " and ' since perl version does. - let line = line.unwrap().replace("\"", "").replace("'", ""); + let line = if strip_quotes { + line.unwrap().replace("\"", "").replace("'", "") + } else { + line.unwrap() + }; if expected.read_line(&mut buf).unwrap() == 0 { panic!( "\noutput has more lines than expected result file: {}", diff --git a/tests/data/collapse-dtrace/mangled.txt b/tests/data/collapse-dtrace/mangled.txt new file mode 100644 index 00000000..7b77cbb0 --- /dev/null +++ b/tests/data/collapse-dtrace/mangled.txt @@ -0,0 +1,94 @@ +CPU ID FUNCTION:NAME + 6 29091 :tick-60s + + + rg`__ZN13grep_searcher8searcher8Searcher11search_path17h4867309d69f27419E+0x10a0 + rg`__ZN2rg15search_parallel28_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17h6e849b55a66fcd85E+0xac + rg`__ZN6ignore4walk6Worker3run17h428457710ae7645aE+0x40b + rg`__ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h71644e3bf9e2bb80E+0x25 + rg`__ZN3std9panicking3try7do_call17h08ca64c12e8a9bb0E.llvm.15516475458848885060+0x25 + rg`__rust_maybe_catch_panic+0x1f + rg`__ZN50_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$8call_box17h8612a2a83552fc2dE+0xa5 + rg`__ZN3std10sys_common6thread12start_thread17he4c2173d5991c786E+0x88 + rg`__ZN3std3sys4unix6thread6Thread3new12thread_start17h8b5ec703435993e3E+0x9 + libsystem_pthread.dylib`_pthread_body+0x7e + libsystem_pthread.dylib`_pthread_start+0x42 + libsystem_pthread.dylib`thread_start+0xd + 1 + + rg`__ZN13grep_searcher11line_buffer10LineBuffer15ensure_capacity17h9368c0fb20c34d8dE + rg`__ZN91_$LT$grep_searcher..searcher..glue..ReadByLine$LT$$u27$s$C$$u20$M$C$$u20$R$C$$u20$S$GT$$GT$3run17h30ecedc997ad7e32E+0x127 + rg`__ZN13grep_searcher8searcher8Searcher11search_path17h4867309d69f27419E+0xb59 + rg`__ZN42_$LT$rg..search..SearchWorker$LT$W$GT$$GT$11search_impl17hcf61284e58f410e0E.llvm.17269878581919215071+0x1585 + rg`__ZN2rg15search_parallel28_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17h6e849b55a66fcd85E+0xac + rg`__ZN6ignore4walk6Worker3run17h428457710ae7645aE+0x40b + rg`__ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h71644e3bf9e2bb80E+0x25 + rg`__ZN3std9panicking3try7do_call17h08ca64c12e8a9bb0E.llvm.15516475458848885060+0x25 + rg`__rust_maybe_catch_panic+0x1f + rg`__ZN50_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$8call_box17h8612a2a83552fc2dE+0xa5 + rg`__ZN3std10sys_common6thread12start_thread17he4c2173d5991c786E+0x88 + rg`__ZN3std3sys4unix6thread6Thread3new12thread_start17h8b5ec703435993e3E+0x9 + libsystem_pthread.dylib`_pthread_body+0x7e + libsystem_pthread.dylib`_pthread_start+0x42 + libsystem_pthread.dylib`thread_start+0xd + 1 + + rg`__ZN14encoding_rs_io4util11PossibleBom8as_slice17h2cc2deba7651dc2aE + rg`__ZN85_$LT$encoding_rs_io..DecodeReaderBytes$LT$R$C$$u20$B$GT$$u20$as$u20$std..io..Read$GT$4read17h19bd185b1317f06cE+0x50 + rg`__ZN76_$LT$grep_searcher..line_buffer..LineBufferReader$LT$$u27$b$C$$u20$R$GT$$GT$4fill17h5bc5eae4aa7991dbE+0x9f + rg`__ZN91_$LT$grep_searcher..searcher..glue..ReadByLine$LT$$u27$s$C$$u20$M$C$$u20$R$C$$u20$S$GT$$GT$3run17h30ecedc997ad7e32E+0x127 + rg`__ZN13grep_searcher8searcher8Searcher11search_path17h4867309d69f27419E+0xb59 + rg`__ZN42_$LT$rg..search..SearchWorker$LT$W$GT$$GT$11search_impl17hcf61284e58f410e0E.llvm.17269878581919215071+0x1585 + rg`__ZN2rg15search_parallel28_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17h6e849b55a66fcd85E+0xac + rg`__ZN6ignore4walk6Worker3run17h428457710ae7645aE+0x40b + rg`__ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h71644e3bf9e2bb80E+0x25 + rg`__ZN3std9panicking3try7do_call17h08ca64c12e8a9bb0E.llvm.15516475458848885060+0x25 + rg`__rust_maybe_catch_panic+0x1f + rg`__ZN50_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$8call_box17h8612a2a83552fc2dE+0xa5 + rg`__ZN3std10sys_common6thread12start_thread17he4c2173d5991c786E+0x88 + rg`__ZN3std3sys4unix6thread6Thread3new12thread_start17h8b5ec703435993e3E+0x9 + libsystem_pthread.dylib`_pthread_body+0x7e + libsystem_pthread.dylib`_pthread_start+0x42 + libsystem_pthread.dylib`thread_start+0xd + 1 + + rg`__ZN6memchr3x863avx6memchr17hc74ea6bdc6b1e860E+0xa1 + rg`__ZN91_$LT$grep_searcher..searcher..glue..ReadByLine$LT$$u27$s$C$$u20$M$C$$u20$R$C$$u20$S$GT$$GT$3run17h30ecedc997ad7e32E+0x127 + rg`__ZN13grep_searcher8searcher8Searcher11search_path17h4867309d69f27419E+0xb59 + rg`__ZN42_$LT$rg..search..SearchWorker$LT$W$GT$$GT$11search_impl17hcf61284e58f410e0E.llvm.17269878581919215071+0x1585 + rg`__ZN2rg15search_parallel28_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17h6e849b55a66fcd85E+0xac + rg`__ZN6ignore4walk6Worker3run17h428457710ae7645aE+0x40b + rg`__ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h71644e3bf9e2bb80E+0x25 + rg`__ZN3std9panicking3try7do_call17h08ca64c12e8a9bb0E.llvm.15516475458848885060+0x25 + rg`__rust_maybe_catch_panic+0x1f + rg`__ZN50_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$8call_box17h8612a2a83552fc2dE+0xa5 + rg`__ZN3std10sys_common6thread12start_thread17he4c2173d5991c786E+0x88 + rg`__ZN3std3sys4unix6thread6Thread3new12thread_start17h8b5ec703435993e3E+0x9 + libsystem_pthread.dylib`_pthread_body+0x7e + libsystem_pthread.dylib`_pthread_start+0x42 + libsystem_pthread.dylib`thread_start+0xd + 1 + + rg`__ZN13grep_searcher11line_buffer10LineBuffer15ensure_capacity17h9368c0fb20c34d8dE+0x1 + rg`__ZN91_$LT$grep_searcher..searcher..glue..ReadByLine$LT$$u27$s$C$$u20$M$C$$u20$R$C$$u20$S$GT$$GT$3run17h30ecedc997ad7e32E+0x127 + rg`__ZN13grep_searcher8searcher8Searcher11search_path17h4867309d69f27419E+0xb59 + rg`__ZN42_$LT$rg..search..SearchWorker$LT$W$GT$$GT$11search_impl17hcf61284e58f410e0E.llvm.17269878581919215071+0x1585 + rg`__ZN2rg15search_parallel28_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17h6e849b55a66fcd85E+0xac + rg`__ZN6ignore4walk6Worker3run17h428457710ae7645aE+0x40b + rg`__ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h71644e3bf9e2bb80E+0x25 + rg`__ZN3std9panicking3try7do_call17h08ca64c12e8a9bb0E.llvm.15516475458848885060+0x25 + rg`__rust_maybe_catch_panic+0x1f + rg`__ZN50_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$8call_box17h8612a2a83552fc2dE+0xa5 + rg`__ZN3std10sys_common6thread12start_thread17he4c2173d5991c786E+0x88 + rg`__ZN3std3sys4unix6thread6Thread3new12thread_start17h8b5ec703435993e3E+0x9 + libsystem_pthread.dylib`_pthread_body+0x7e + libsystem_pthread.dylib`_pthread_start+0x42 + libsystem_pthread.dylib`thread_start+0xd + 1 + + rg`__ZN6memchr3x863avx6memchr17hc74ea6bdc6b1e860E+0xa6 + rg`__ZN75_$LT$grep_regex..matcher..RegexMatcher$u20$as$u20$grep_matcher..Matcher$GT$19find_candidate_line17h33f9c077c6589c2aE+0x14e + rg`__ZN76_$LT$grep_searcher..searcher..core..Core$LT$$u27$s$C$$u20$M$C$$u20$S$GT$$GT$13match_by_line17hed1d0226a7a67d03E+0x813 + rg`__ZN91_$LT$grep_searcher..searcher..glue..ReadByLine$LT$$u27$s$C$$u20$M$C$$u20$R$C$$u20$S$GT$$GT$3run17h30ecedc997ad7e32E+0x26f + rg`__ZN13grep_searcher8searcher8Searcher11search_path17h4867309d69f27419E+0xb59 + rg`__ZN42_$LT$rg..search..SearchWorker$LT$W$GT$$GT$11search_impl17hcf61284e58f410e0E.llvm.17269878581919215071+0x1585 diff --git a/tests/data/collapse-dtrace/results/demangled.txt b/tests/data/collapse-dtrace/results/demangled.txt new file mode 100644 index 00000000..7958c749 --- /dev/null +++ b/tests/data/collapse-dtrace/results/demangled.txt @@ -0,0 +1,4 @@ +libsystem_pthread.dylib`thread_start;libsystem_pthread.dylib`_pthread_start;libsystem_pthread.dylib`_pthread_body;rg`std::sys::unix::thread::Thread::new::thread_start;rg`std::sys_common::thread::start_thread;rg`>::call_box;rg`__rust_maybe_catch_panic;rg`std::panicking::try::do_call;rg`std::sys_common::backtrace::__rust_begin_short_backtrace;rg`ignore::walk::Worker::run;rg`rg::search_parallel::{{closure}}::{{closure}};rg`>::search_impl;rg`grep_searcher::searcher::Searcher::search_path;rg`>::run;rg`>::fill;rg` as std::io::Read>::read;rg`encoding_rs_io::util::PossibleBom::as_slice 1 +libsystem_pthread.dylib`thread_start;libsystem_pthread.dylib`_pthread_start;libsystem_pthread.dylib`_pthread_body;rg`std::sys::unix::thread::Thread::new::thread_start;rg`std::sys_common::thread::start_thread;rg`>::call_box;rg`__rust_maybe_catch_panic;rg`std::panicking::try::do_call;rg`std::sys_common::backtrace::__rust_begin_short_backtrace;rg`ignore::walk::Worker::run;rg`rg::search_parallel::{{closure}}::{{closure}};rg`>::search_impl;rg`grep_searcher::searcher::Searcher::search_path;rg`>::run;rg`grep_searcher::line_buffer::LineBuffer::ensure_capacity 2 +libsystem_pthread.dylib`thread_start;libsystem_pthread.dylib`_pthread_start;libsystem_pthread.dylib`_pthread_body;rg`std::sys::unix::thread::Thread::new::thread_start;rg`std::sys_common::thread::start_thread;rg`>::call_box;rg`__rust_maybe_catch_panic;rg`std::panicking::try::do_call;rg`std::sys_common::backtrace::__rust_begin_short_backtrace;rg`ignore::walk::Worker::run;rg`rg::search_parallel::{{closure}}::{{closure}};rg`>::search_impl;rg`grep_searcher::searcher::Searcher::search_path;rg`>::run;rg`memchr::x86::avx::memchr 1 +libsystem_pthread.dylib`thread_start;libsystem_pthread.dylib`_pthread_start;libsystem_pthread.dylib`_pthread_body;rg`std::sys::unix::thread::Thread::new::thread_start;rg`std::sys_common::thread::start_thread;rg`>::call_box;rg`__rust_maybe_catch_panic;rg`std::panicking::try::do_call;rg`std::sys_common::backtrace::__rust_begin_short_backtrace;rg`ignore::walk::Worker::run;rg`rg::search_parallel::{{closure}}::{{closure}};rg`grep_searcher::searcher::Searcher::search_path 1 diff --git a/tests/data/collapse-perf/mangled.txt b/tests/data/collapse-perf/mangled.txt new file mode 100644 index 00000000..49ee0c95 --- /dev/null +++ b/tests/data/collapse-perf/mangled.txt @@ -0,0 +1,99 @@ +inferno-flamegr 11728 150317.785308: 250000 cpu-clock:uhH: + 7f0f22ebd4ba handle_intel.constprop.1+0x6a (/usr/lib/libc-2.28.so) + 7f0f22e3cc00 init_cacheinfo+0x110 (/usr/lib/libc-2.28.so) + 7f0f2304a549 call_init.part.0+0x99 (/usr/lib/ld-2.28.so) + 7f0f2304a649 _dl_init+0x79 (/usr/lib/ld-2.28.so) + 7f0f2303c039 _dl_start_user+0x31 (/usr/lib/ld-2.28.so) + +inferno-flamegr 11728 150317.788989: 250000 cpu-clock:uhH: + 560b65a8aa4d _ZN156_$LT$std..collections..hash..table..FullBucket$LT$K$C$$u20$V$C$$u20$$RF$$u27$t$u20$mut$u20$std..collections..hash..table..RawTable$LT$K$C$$u20$V$GT$$GT$$GT$4take17hf02b8d52a6d1fac5E+0x1cd (inlined) + 560b65a8aa4d _ZN3std11collections4hash3map12pop_internal17h8e26b8e3b84b0987E+0x1cd (inlined) + 560b65a8aa4d _ZN72_$LT$std..collections..hash..map..HashMap$LT$K$C$$u20$V$C$$u20$S$GT$$GT$6remove28_$u7b$$u7b$closure$u7d$$u7d$17ha764a6bc24af09ecE+0x1cd (inlined) + 560b65a8aa4d _ZN38_$LT$core..option..Option$LT$T$GT$$GT$3map17h540246040b56a5bcE+0x1cd (inlined) + 560b65a8aa4d _ZN72_$LT$std..collections..hash..map..HashMap$LT$K$C$$u20$V$C$$u20$S$GT$$GT$6remove17h5327add6a3bd1019E+0x1cd (inferno/target/release/inferno-flamegraph) + 560b65a8e354 _ZN7inferno10flamegraph5merge4flow17hfc9bea06782bbbe8E+0x5b4 (inferno/target/release/inferno-flamegraph) + 560b65a8ed39 _ZN7inferno10flamegraph5merge6frames17hacfe2d67301633c2E+0x419 (inferno/target/release/inferno-flamegraph) + 560b65a6dec4 _ZN7inferno10flamegraph10from_lines17hbe700b4595c52449E+0xb04 (inferno/target/release/inferno-flamegraph) + 560b65a6cd95 _ZN7inferno10flamegraph12from_readers17h1f4a09fd80fc6478E+0x12d5 (inlined) + 560b65a6cd95 _ZN7inferno10flamegraph11from_reader17h1b0a3b19342e0102E+0x12d5 (inlined) + 560b65a6cd95 _ZN7inferno10flamegraph10from_files17he2ae59d000587309E+0x12d5 (inferno/target/release/inferno-flamegraph) + 560b65a88789 _ZN18inferno_flamegraph4main17h80ee04565b2fc086E+0x929 (inferno/target/release/inferno-flamegraph) + 560b65a72c31 _ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h9efaa4abd3ddf1b3E+0x11 (inferno/target/release/inferno-flamegraph) + 560b65b95492 _ZN3std2rt19lang_start_internal28_$u7b$$u7b$closure$u7d$$u7d$17hdfc28107b5be47c9E+0x12 (inlined) + 560b65b95492 _ZN3std9panicking3try7do_call17h69790245ac2d03feE+0x12 (inferno/target/release/inferno-flamegraph) + 560b65ba38d9 __rust_maybe_catch_panic+0x19 (inferno/target/release/inferno-flamegraph) + 560b65b95e63 _ZN3std9panicking3try17h9c1cbc5599e1efbfE+0x203 (inlined) + 560b65b95e63 _ZN3std5panic12catch_unwind17h0562757d03ff60b3E+0x203 (inlined) + 560b65b95e63 _ZN3std2rt19lang_start_internal17h540c897fe52ba9c5E+0x203 (inferno/target/release/inferno-flamegraph) + 560b65a88e37 main+0x27 (inferno/target/release/inferno-flamegraph) + 7f0f22e3d222 __libc_start_main+0xf2 (/usr/lib/libc-2.28.so) + 560b65a6b15d _start+0x2d (inferno/target/release/inferno-flamegraph) + +inferno-flamegr 11728 150317.789122: 250000 cpu-clock:uhH: + 560b65ba9b6f _ZN4core5slice6memchr6memchr17h4201b5ac6ed87fc2E+0xef (inferno/target/release/inferno-flamegraph) + 560b65a8cfdc _ZN109_$LT$core..str..pattern..CharSearcher$LT$$u27$a$GT$$u20$as$u20$core..str..pattern..Searcher$LT$$u27$a$GT$$GT$10next_match17h57479c8178dcbc98E+0x4c (inlined) + 560b65a8cfdc _ZN56_$LT$core..str..SplitInternal$LT$$u27$a$C$$u20$P$GT$$GT$4next17hc59dfcb114a11b7eE+0x4c (inferno/target/release/inferno-flamegraph) + 560b65a8df48 _ZN7inferno10flamegraph5merge4flow17hfc9bea06782bbbe8E+0x1a8 (inferno/target/release/inferno-flamegraph) + 560b65a8df48 _ZN38_$LT$core..iter..Peekable$LT$I$GT$$GT$4peek17h9d6fcd3640686ee1E+0x1a8 (inlined) + 560b65a8df48 _ZN7inferno10flamegraph5merge4flow17hfc9bea06782bbbe8E+0x1a8 (inferno/target/release/inferno-flamegraph) + 560b65a8ed39 _ZN7inferno10flamegraph5merge6frames17hacfe2d67301633c2E+0x419 (inferno/target/release/inferno-flamegraph) + 560b65a6dec4 _ZN7inferno10flamegraph10from_lines17hbe700b4595c52449E+0xb04 (inferno/target/release/inferno-flamegraph) + 560b65a6cd95 _ZN7inferno10flamegraph12from_readers17h1f4a09fd80fc6478E+0x12d5 (inlined) + 560b65a6cd95 _ZN7inferno10flamegraph11from_reader17h1b0a3b19342e0102E+0x12d5 (inlined) + 560b65a6cd95 _ZN7inferno10flamegraph10from_files17he2ae59d000587309E+0x12d5 (inferno/target/release/inferno-flamegraph) + 560b65a88789 _ZN18inferno_flamegraph4main17h80ee04565b2fc086E+0x929 (inferno/target/release/inferno-flamegraph) + 560b65a72c31 _ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h9efaa4abd3ddf1b3E+0x11 (inferno/target/release/inferno-flamegraph) + 560b65b95492 _ZN3std2rt19lang_start_internal28_$u7b$$u7b$closure$u7d$$u7d$17hdfc28107b5be47c9E+0x12 (inlined) + 560b65b95492 _ZN3std9panicking3try7do_call17h69790245ac2d03feE+0x12 (inferno/target/release/inferno-flamegraph) + 560b65ba38d9 __rust_maybe_catch_panic+0x19 (inferno/target/release/inferno-flamegraph) + 560b65b95e63 _ZN3std9panicking3try17h9c1cbc5599e1efbfE+0x203 (inlined) + 560b65b95e63 _ZN3std5panic12catch_unwind17h0562757d03ff60b3E+0x203 (inlined) + 560b65b95e63 _ZN3std2rt19lang_start_internal17h540c897fe52ba9c5E+0x203 (inferno/target/release/inferno-flamegraph) + 560b65a88e37 main+0x27 (inferno/target/release/inferno-flamegraph) + 7f0f22e3d222 __libc_start_main+0xf2 (/usr/lib/libc-2.28.so) + 560b65a6b15d _start+0x2d (inferno/target/release/inferno-flamegraph) + +inferno-flamegr 11728 150317.790329: 250000 cpu-clock:uhH: + 7f0f22f74cf0 __memcmp_avx2_movbe+0x0 (/usr/lib/libc-2.28.so) + 560b65a900d9 _ZN68_$LT$$u5b$A$u5d$$u20$as$u20$core..slice..SlicePartialEq$LT$A$GT$$GT$5equal17h2b4f655ef983c429E+0xc9 (inlined) + 560b65a900d9 _ZN4core5slice81_$LT$impl$u20$core..cmp..PartialEq$LT$$u5b$B$u5d$$GT$$u20$for$u20$$u5b$A$u5d$$GT$2eq17h05db67084362255dE+0xc9 (inlined) + 560b65a900d9 _ZN4core3cmp5impls91_$LT$impl$u20$core..cmp..PartialEq$LT$$RF$$u27$b$u20$B$GT$$u20$for$u20$$RF$$u27$a$u20$A$GT$2eq17h80fb884a22a2c02fE+0xc9 (inlined) + 560b65a900d9 _ZN116_$LT$core..str..pattern..CharSearcher$LT$$u27$a$GT$$u20$as$u20$core..str..pattern..ReverseSearcher$LT$$u27$a$GT$$GT$15next_match_back17h09d544049dd719bbE+0xc9 (inlined) + 560b65a900d9 _ZN4core3str21_$LT$impl$u20$str$GT$5rfind17hf9dea3c1f950070bE+0xc9 (inlined) + 560b65a900d9 _ZN7inferno10flamegraph5merge13rfind_samples17h9cb7004aaf522de1E+0xc9 (inferno/target/release/inferno-flamegraph) + 560b65a8fd55 _ZN7inferno10flamegraph5merge14parse_nsamples17hce2b37809d3f7c38E+0x25 (inferno/target/release/inferno-flamegraph) + 560b65a8eaa8 _ZN7inferno10flamegraph5merge6frames17hacfe2d67301633c2E+0x188 (inferno/target/release/inferno-flamegraph) + 560b65a6dec4 _ZN7inferno10flamegraph10from_lines17hbe700b4595c52449E+0xb04 (inferno/target/release/inferno-flamegraph) + 560b65a6cd95 _ZN7inferno10flamegraph12from_readers17h1f4a09fd80fc6478E+0x12d5 (inlined) + 560b65a6cd95 _ZN7inferno10flamegraph11from_reader17h1b0a3b19342e0102E+0x12d5 (inlined) + 560b65a6cd95 _ZN7inferno10flamegraph10from_files17he2ae59d000587309E+0x12d5 (inferno/target/release/inferno-flamegraph) + 560b65a88789 _ZN18inferno_flamegraph4main17h80ee04565b2fc086E+0x929 (inferno/target/release/inferno-flamegraph) + 560b65a72c31 _ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h9efaa4abd3ddf1b3E+0x11 (inferno/target/release/inferno-flamegraph) + 560b65b95492 _ZN3std2rt19lang_start_internal28_$u7b$$u7b$closure$u7d$$u7d$17hdfc28107b5be47c9E+0x12 (inlined) + 560b65b95492 _ZN3std9panicking3try7do_call17h69790245ac2d03feE+0x12 (inferno/target/release/inferno-flamegraph) + 560b65ba38d9 __rust_maybe_catch_panic+0x19 (inferno/target/release/inferno-flamegraph) + 560b65b95e63 _ZN3std9panicking3try17h9c1cbc5599e1efbfE+0x203 (inlined) + 560b65b95e63 _ZN3std5panic12catch_unwind17h0562757d03ff60b3E+0x203 (inlined) + 560b65b95e63 _ZN3std2rt19lang_start_internal17h540c897fe52ba9c5E+0x203 (inferno/target/release/inferno-flamegraph) + 560b65a88e37 main+0x27 (inferno/target/release/inferno-flamegraph) + 7f0f22e3d222 __libc_start_main+0xf2 (/usr/lib/libc-2.28.so) + 560b65a6b15d _start+0x2d (inferno/target/release/inferno-flamegraph) + +inferno-flamegr 11728 150317.791447: 250000 cpu-clock:uhH: + 560b65a8e7a8 _ZN7inferno10flamegraph5merge4flow17hfc9bea06782bbbe8E+0xa08 (inferno/target/release/inferno-flamegraph) + 560b65a8ed39 _ZN7inferno10flamegraph5merge6frames17hacfe2d67301633c2E+0x419 (inferno/target/release/inferno-flamegraph) + 560b65a6dec4 _ZN7inferno10flamegraph10from_lines17hbe700b4595c52449E+0xb04 (inferno/target/release/inferno-flamegraph) + 560b65a6cd95 _ZN7inferno10flamegraph12from_readers17h1f4a09fd80fc6478E+0x12d5 (inlined) + 560b65a6cd95 _ZN7inferno10flamegraph11from_reader17h1b0a3b19342e0102E+0x12d5 (inlined) + 560b65a6cd95 _ZN7inferno10flamegraph10from_files17he2ae59d000587309E+0x12d5 (inferno/target/release/inferno-flamegraph) + 560b65a88789 _ZN18inferno_flamegraph4main17h80ee04565b2fc086E+0x929 (inferno/target/release/inferno-flamegraph) + 560b65a72c31 _ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h9efaa4abd3ddf1b3E+0x11 (inferno/target/release/inferno-flamegraph) + 560b65b95492 _ZN3std2rt19lang_start_internal28_$u7b$$u7b$closure$u7d$$u7d$17hdfc28107b5be47c9E+0x12 (inlined) + 560b65b95492 _ZN3std9panicking3try7do_call17h69790245ac2d03feE+0x12 (inferno/target/release/inferno-flamegraph) + 560b65ba38d9 __rust_maybe_catch_panic+0x19 (inferno/target/release/inferno-flamegraph) + 560b65b95e63 _ZN3std9panicking3try17h9c1cbc5599e1efbfE+0x203 (inlined) + 560b65b95e63 _ZN3std5panic12catch_unwind17h0562757d03ff60b3E+0x203 (inlined) + 560b65b95e63 _ZN3std2rt19lang_start_internal17h540c897fe52ba9c5E+0x203 (inferno/target/release/inferno-flamegraph) + 560b65a88e37 main+0x27 (inferno/target/release/inferno-flamegraph) + 7f0f22e3d222 __libc_start_main+0xf2 (/usr/lib/libc-2.28.so) + 560b65a6b15d _start+0x2d (inferno/target/release/inferno-flamegraph) diff --git a/tests/data/collapse-perf/results/demangled.txt b/tests/data/collapse-perf/results/demangled.txt new file mode 100644 index 00000000..f157b58c --- /dev/null +++ b/tests/data/collapse-perf/results/demangled.txt @@ -0,0 +1,4 @@ +inferno-flamegr;_dl_start_user;_dl_init;call_init.part.0;init_cacheinfo;handle_intel.constprop.1 1 +inferno-flamegr;_start;__libc_start_main;main;std::rt::lang_start_internal;std::panic::catch_unwind;std::panicking::try;__rust_maybe_catch_panic;std::panicking::try::do_call;std::rt::lang_start_internal::{{closure}};std::rt::lang_start::{{closure}};inferno_flamegraph::main;inferno::flamegraph::from_files;inferno::flamegraph::from_reader;inferno::flamegraph::from_readers;inferno::flamegraph::from_lines;inferno::flamegraph::merge::frames;inferno::flamegraph::merge::flow;>::peek;inferno::flamegraph::merge::flow;>::next; as core::str::pattern::Searcher<'a>>::next_match;core::slice::memchr::memchr 1 +inferno-flamegr;_start;__libc_start_main;main;std::rt::lang_start_internal;std::panic::catch_unwind;std::panicking::try;__rust_maybe_catch_panic;std::panicking::try::do_call;std::rt::lang_start_internal::{{closure}};std::rt::lang_start::{{closure}};inferno_flamegraph::main;inferno::flamegraph::from_files;inferno::flamegraph::from_reader;inferno::flamegraph::from_readers;inferno::flamegraph::from_lines;inferno::flamegraph::merge::frames;inferno::flamegraph::merge::flow;>::remove;>::map;>::remove::{{closure}};std::collections::hash::map::pop_internal;>>::take 1 +inferno-flamegr;_start;__libc_start_main;main;std::rt::lang_start_internal;std::panic::catch_unwind;std::panicking::try;__rust_maybe_catch_panic;std::panicking::try::do_call;std::rt::lang_start_internal::{{closure}};std::rt::lang_start::{{closure}};inferno_flamegraph::main;inferno::flamegraph::from_files;inferno::flamegraph::from_reader;inferno::flamegraph::from_readers;inferno::flamegraph::from_lines;inferno::flamegraph::merge::frames;inferno::flamegraph::merge::parse_nsamples;inferno::flamegraph::merge::rfind_samples;core::str::::rfind; as core::str::pattern::ReverseSearcher<'a>>::next_match_back;core::cmp::impls:: for &'a A>::eq;core::slice:: for [A]>::eq;<[A] as core::slice::SlicePartialEq>::equal;__memcmp_avx2_movbe 1 From 11a3ceda92910200358f3347417b465563e7eef8 Mon Sep 17 00:00:00 2001 From: Jason Rodney Hansen Date: Tue, 2 Jul 2019 08:06:58 -0600 Subject: [PATCH 2/6] Remove symbolic-common from Cargo.toml --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index fa81aa4b..c7ed8203 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,6 @@ lazy_static = "1.3.0" fnv = "1.0.3" itoa = "0.4.3" indexmap = "1.0" -symbolic-common = "6.1.3" symbolic-demangle = "6.1.3" [dev-dependencies] From c6e46b56f83c8a09eda12f3e1fa1ba2344ba3bdd Mon Sep 17 00:00:00 2001 From: Jason Rodney Hansen Date: Tue, 2 Jul 2019 08:27:23 -0600 Subject: [PATCH 3/6] Use Cow::Borrowed --- src/collapse/dtrace.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/collapse/dtrace.rs b/src/collapse/dtrace.rs index 32fa912a..7c80bce3 100644 --- a/src/collapse/dtrace.rs +++ b/src/collapse/dtrace.rs @@ -188,7 +188,7 @@ impl Folder { } let frame = if frame.is_empty() { - Cow::Owned("-".to_owned()) + Cow::Borrowed("-") } else if self.opt.demangle { let mut parts = frame.split('`'); if let (Some(pname), Some(func)) = (parts.next(), parts.next()) { From 089445e845fd9bd09f7e4df582401c047220467f Mon Sep 17 00:00:00 2001 From: Jason Rodney Hansen Date: Tue, 2 Jul 2019 08:28:48 -0600 Subject: [PATCH 4/6] Format --- tests/collapse_common/mod.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/collapse_common/mod.rs b/tests/collapse_common/mod.rs index 80b1297e..90d8c7f9 100644 --- a/tests/collapse_common/mod.rs +++ b/tests/collapse_common/mod.rs @@ -69,8 +69,12 @@ where testing_logger::validate(asserter); } -pub(crate) fn compare_results(result: R, mut expected: E, expected_file: &str, strip_quotes: bool) -where +pub(crate) fn compare_results( + result: R, + mut expected: E, + expected_file: &str, + strip_quotes: bool, +) where R: BufRead, E: BufRead, { From 8122533a857e5f22bee36d50baf09e18807a4cf7 Mon Sep 17 00:00:00 2001 From: Jason Rodney Hansen Date: Tue, 2 Jul 2019 09:34:54 -0600 Subject: [PATCH 5/6] Make demangle work with includeoffset --- src/collapse/dtrace.rs | 24 +++++++++++++------ tests/collapse-dtrace.rs | 15 ++++++++++++ .../results/demangled_with_offsets.txt | 4 ++++ 3 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 tests/data/collapse-dtrace/results/demangled_with_offsets.txt diff --git a/src/collapse/dtrace.rs b/src/collapse/dtrace.rs index 7c80bce3..ae96fee5 100644 --- a/src/collapse/dtrace.rs +++ b/src/collapse/dtrace.rs @@ -148,7 +148,7 @@ impl Folder { let mut could_be_cpp = false; let mut has_semicolon = false; let mut last_offset = line.len(); - // This seems risly but dtrace stacks are c-strings as can be seen in the function + // This seems risky, but dtrace stacks are c-strings as can be seen in the function // responsible for printing them: // https://github.com/opendtrace/opendtrace/blob/1a03ea5576a9219a43f28b4f159ff8a4b1f9a9fd/lib/libdtrace/common/dt_consume.c#L1331 let bytes = line.as_bytes(); @@ -169,6 +169,21 @@ impl Folder { ) } + fn demangle<'a>(&self, frame: &'a str) -> Cow<'a, str> { + let mut parts = frame.splitn(2, '`'); + if let (Some(pname), Some(func)) = (parts.next(), parts.next()) { + if self.opt.includeoffset { + let mut parts = func.rsplitn(2, '+'); + if let (Some(offset), Some(func)) = (parts.next(), parts.next()) { + return Cow::Owned(format!("{}`{}+{}", pname, demangle(func), offset)); + } + } + return Cow::Owned(format!("{}`{}", pname, demangle(func))); + } + + Cow::Borrowed(frame) + } + // we have a stack line that shows one stack entry from the preceeding event, like: // // unix`tsc_gethrtimeunscaled+0x21 @@ -190,12 +205,7 @@ impl Folder { let frame = if frame.is_empty() { Cow::Borrowed("-") } else if self.opt.demangle { - let mut parts = frame.split('`'); - if let (Some(pname), Some(func)) = (parts.next(), parts.next()) { - Cow::Owned(format!("{}`{}", pname, demangle(func))) - } else { - Cow::Borrowed(frame) - } + self.demangle(frame) } else { Cow::Borrowed(frame) }; diff --git a/tests/collapse-dtrace.rs b/tests/collapse-dtrace.rs index 7c97e2e8..7667ef5d 100644 --- a/tests/collapse-dtrace.rs +++ b/tests/collapse-dtrace.rs @@ -125,6 +125,21 @@ fn collapse_dtrace_demangle() { .unwrap() } +#[test] +fn collapse_dtrace_demangle_includeoffset() { + let test_file = "./tests/data/collapse-dtrace/mangled.txt"; + let result_file = "./tests/data/collapse-dtrace/results/demangled_with_offsets.txt"; + test_collapse_dtrace( + test_file, + result_file, + Options { + includeoffset: true, + demangle: true, + }, + ) + .unwrap() +} + #[test] fn collapse_dtrace_cli() { let input_file = "./flamegraph/example-dtrace-stacks.txt"; diff --git a/tests/data/collapse-dtrace/results/demangled_with_offsets.txt b/tests/data/collapse-dtrace/results/demangled_with_offsets.txt new file mode 100644 index 00000000..aa1ec551 --- /dev/null +++ b/tests/data/collapse-dtrace/results/demangled_with_offsets.txt @@ -0,0 +1,4 @@ +libsystem_pthread.dylib`thread_start+0xd;libsystem_pthread.dylib`_pthread_start+0x42;libsystem_pthread.dylib`_pthread_body+0x7e;rg`std::sys::unix::thread::Thread::new::thread_start+0x9;rg`std::sys_common::thread::start_thread+0x88;rg`>::call_box+0xa5;rg`__rust_maybe_catch_panic+0x1f;rg`std::panicking::try::do_call+0x25;rg`std::sys_common::backtrace::__rust_begin_short_backtrace+0x25;rg`ignore::walk::Worker::run+0x40b;rg`rg::search_parallel::{{closure}}::{{closure}}+0xac;rg`>::search_impl+0x1585;rg`grep_searcher::searcher::Searcher::search_path+0xb59;rg`>::run+0x127;rg`>::fill+0x9f;rg` as std::io::Read>::read+0x50;rg`encoding_rs_io::util::PossibleBom::as_slice 1 +libsystem_pthread.dylib`thread_start+0xd;libsystem_pthread.dylib`_pthread_start+0x42;libsystem_pthread.dylib`_pthread_body+0x7e;rg`std::sys::unix::thread::Thread::new::thread_start+0x9;rg`std::sys_common::thread::start_thread+0x88;rg`>::call_box+0xa5;rg`__rust_maybe_catch_panic+0x1f;rg`std::panicking::try::do_call+0x25;rg`std::sys_common::backtrace::__rust_begin_short_backtrace+0x25;rg`ignore::walk::Worker::run+0x40b;rg`rg::search_parallel::{{closure}}::{{closure}}+0xac;rg`>::search_impl+0x1585;rg`grep_searcher::searcher::Searcher::search_path+0xb59;rg`>::run+0x127;rg`grep_searcher::line_buffer::LineBuffer::ensure_capacity 2 +libsystem_pthread.dylib`thread_start+0xd;libsystem_pthread.dylib`_pthread_start+0x42;libsystem_pthread.dylib`_pthread_body+0x7e;rg`std::sys::unix::thread::Thread::new::thread_start+0x9;rg`std::sys_common::thread::start_thread+0x88;rg`>::call_box+0xa5;rg`__rust_maybe_catch_panic+0x1f;rg`std::panicking::try::do_call+0x25;rg`std::sys_common::backtrace::__rust_begin_short_backtrace+0x25;rg`ignore::walk::Worker::run+0x40b;rg`rg::search_parallel::{{closure}}::{{closure}}+0xac;rg`>::search_impl+0x1585;rg`grep_searcher::searcher::Searcher::search_path+0xb59;rg`>::run+0x127;rg`memchr::x86::avx::memchr 1 +libsystem_pthread.dylib`thread_start+0xd;libsystem_pthread.dylib`_pthread_start+0x42;libsystem_pthread.dylib`_pthread_body+0x7e;rg`std::sys::unix::thread::Thread::new::thread_start+0x9;rg`std::sys_common::thread::start_thread+0x88;rg`>::call_box+0xa5;rg`__rust_maybe_catch_panic+0x1f;rg`std::panicking::try::do_call+0x25;rg`std::sys_common::backtrace::__rust_begin_short_backtrace+0x25;rg`ignore::walk::Worker::run+0x40b;rg`rg::search_parallel::{{closure}}::{{closure}}+0xac;rg`grep_searcher::searcher::Searcher::search_path 1 From e8397b260a9e1f46c744c7cd550b4f447f08721c Mon Sep 17 00:00:00 2001 From: Jason Rodney Hansen Date: Tue, 2 Jul 2019 14:23:10 -0600 Subject: [PATCH 6/6] Use symbolic_demangle::demangle --- src/collapse/dtrace.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/collapse/dtrace.rs b/src/collapse/dtrace.rs index ae96fee5..1c3f3123 100644 --- a/src/collapse/dtrace.rs +++ b/src/collapse/dtrace.rs @@ -5,7 +5,6 @@ use std::borrow::Cow; use std::collections::VecDeque; use std::io; use std::io::prelude::*; -use symbolic_demangle::demangle; /// Settings that change how frames are named from the incoming stack traces. /// @@ -175,10 +174,15 @@ impl Folder { if self.opt.includeoffset { let mut parts = func.rsplitn(2, '+'); if let (Some(offset), Some(func)) = (parts.next(), parts.next()) { - return Cow::Owned(format!("{}`{}+{}", pname, demangle(func), offset)); + return Cow::Owned(format!( + "{}`{}+{}", + pname, + symbolic_demangle::demangle(func), + offset + )); } } - return Cow::Owned(format!("{}`{}", pname, demangle(func))); + return Cow::Owned(format!("{}`{}", pname, symbolic_demangle::demangle(func))); } Cow::Borrowed(frame)