From a6f8b8a2116f0ea7e31d572d3120508678ed8079 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Thu, 2 Jul 2020 11:27:15 -0700 Subject: Generating the coverage map rustc now generates the coverage map and can support (limited) coverage report generation, at the function level. Example: $ BUILD=$HOME/rust/build/x86_64-unknown-linux-gnu $ $BUILD/stage1/bin/rustc -Zinstrument-coverage \ $HOME/rust/src/test/run-make-fulldeps/instrument-coverage/main.rs $ LLVM_PROFILE_FILE="main.profraw" ./main called $ $BUILD/llvm/bin/llvm-profdata merge -sparse main.profraw -o main.profdata $ $BUILD/llvm/bin/llvm-cov show --instr-profile=main.profdata main 1| 1|pub fn will_be_called() { 2| 1| println!("called"); 3| 1|} 4| | 5| 0|pub fn will_not_be_called() { 6| 0| println!("should not have been called"); 7| 0|} 8| | 9| 1|fn main() { 10| 1| let less = 1; 11| 1| let more = 100; 12| 1| 13| 1| if less < more { 14| 1| will_be_called(); 15| 1| } else { 16| 1| will_not_be_called(); 17| 1| } 18| 1|} --- src/tools/compiletest/src/common.rs | 3 +++ src/tools/compiletest/src/main.rs | 5 +++++ src/tools/compiletest/src/runtest.rs | 4 ++++ src/tools/rust-demangler/Cargo.toml | 12 +++++++++++ src/tools/rust-demangler/main.rs | 39 ++++++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+) create mode 100644 src/tools/rust-demangler/Cargo.toml create mode 100644 src/tools/rust-demangler/main.rs (limited to 'src/tools') diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 703b87634ce..5f7373be659 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -186,6 +186,9 @@ pub struct Config { /// The rustdoc executable. pub rustdoc_path: Option, + /// The rust-demangler executable. + pub rust_demangler_path: Option, + /// The Python executable to use for LLDB. pub lldb_python: String, diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 97272f1a9c1..07eba22c6ee 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -53,6 +53,7 @@ pub fn parse_config(args: Vec) -> Config { .reqopt("", "run-lib-path", "path to target shared libraries", "PATH") .reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH") .optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH") + .optopt("", "rust-demangler-path", "path to rust-demangler to use in tests", "PATH") .reqopt("", "lldb-python", "path to python to use for doc tests", "PATH") .reqopt("", "docck-python", "path to python to use for doc tests", "PATH") .optopt("", "valgrind-path", "path to Valgrind executable for Valgrind tests", "PROGRAM") @@ -182,6 +183,7 @@ pub fn parse_config(args: Vec) -> Config { run_lib_path: make_absolute(opt_path(matches, "run-lib-path")), rustc_path: opt_path(matches, "rustc-path"), rustdoc_path: matches.opt_str("rustdoc-path").map(PathBuf::from), + rust_demangler_path: matches.opt_str("rust-demangler-path").map(PathBuf::from), lldb_python: matches.opt_str("lldb-python").unwrap(), docck_python: matches.opt_str("docck-python").unwrap(), valgrind_path: matches.opt_str("valgrind-path"), @@ -246,6 +248,7 @@ pub fn log_config(config: &Config) { logv(c, format!("run_lib_path: {:?}", config.run_lib_path)); logv(c, format!("rustc_path: {:?}", config.rustc_path.display())); logv(c, format!("rustdoc_path: {:?}", config.rustdoc_path)); + logv(c, format!("rust_demangler_path: {:?}", config.rust_demangler_path)); logv(c, format!("src_base: {:?}", config.src_base.display())); logv(c, format!("build_base: {:?}", config.build_base.display())); logv(c, format!("stage_id: {}", config.stage_id)); @@ -479,6 +482,8 @@ fn common_inputs_stamp(config: &Config) -> Stamp { stamp.add_path(&rustdoc_path); stamp.add_path(&rust_src_dir.join("src/etc/htmldocck.py")); } + // FIXME(richkadel): Do I need to add an `if let Some(rust_demangler_path) contribution to the + // stamp here as well? // Compiletest itself. stamp.add_dir(&rust_src_dir.join("src/tools/compiletest/")); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index dd0c68ecd49..f09f7621aa1 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2739,6 +2739,10 @@ impl<'test> TestCx<'test> { cmd.env("RUSTDOC", cwd.join(rustdoc)); } + if let Some(ref rust_demangler) = self.config.rust_demangler_path { + cmd.env("RUST_DEMANGLER", cwd.join(rust_demangler)); + } + if let Some(ref node) = self.config.nodejs { cmd.env("NODE", node); } diff --git a/src/tools/rust-demangler/Cargo.toml b/src/tools/rust-demangler/Cargo.toml new file mode 100644 index 00000000000..0b8d974d255 --- /dev/null +++ b/src/tools/rust-demangler/Cargo.toml @@ -0,0 +1,12 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rust-demangler" +version = "0.0.0" +edition = "2018" + +[dependencies] +rustc-demangle = "0.1" + +[[bin]] +name = "rust-demangler" +path = "main.rs" diff --git a/src/tools/rust-demangler/main.rs b/src/tools/rust-demangler/main.rs new file mode 100644 index 00000000000..a9f1011c450 --- /dev/null +++ b/src/tools/rust-demangler/main.rs @@ -0,0 +1,39 @@ +//! Demangles rustc mangled names. +//! +//! This tool uses https://crates.io/crates/rustc-demangle to convert an input buffer of +//! newline-separated mangled names into their demangled translations. +//! +//! This tool can be leveraged by other applications that support third-party demanglers. +//! It takes a list of mangled names (one per line) on standard input, and prints a corresponding +//! list of demangled names. The tool is designed to support other programs that can leverage a +//! third-party demangler, such as `llvm-cov`, via the `-Xdemangler=` option. +//! +//! To use `rust-demangler`, first build the tool with: +//! +//! ```shell +//! $ ./x.py build rust-demangler +//! ``` +//! +//! Then, with `llvm-cov` for example, add the `-Xdemangler=...` option: +//! +//! ```shell +//! $ TARGET="${PWD}/build/x86_64-unknown-linux-gnu" +//! $ "${TARGET}"/llvm/bin/llvm-cov show --Xdemangler="${TARGET}"/stage0-tools-bin/rust-demangler \ +//! --instr-profile=main.profdata ./main --show-line-counts-or-regions +//! ``` + +use rustc_demangle::demangle; +use std::io::{self, Read, Write}; + +fn main() -> io::Result<()> { + let mut buffer = String::new(); + io::stdin().read_to_string(&mut buffer)?; + let lines = buffer.lines(); + let mut demangled = Vec::new(); + for mangled in lines { + demangled.push(demangle(mangled).to_string()); + } + demangled.push("".to_string()); + io::stdout().write_all(demangled.join("\n").as_bytes())?; + Ok(()) +} -- cgit 1.4.1-3-g733a5