]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #68391 - tmiasko:compiletest-debuginfo, r=alexcrichton
authorbors <bors@rust-lang.org>
Thu, 23 Jan 2020 19:39:07 +0000 (19:39 +0000)
committerbors <bors@rust-lang.org>
Thu, 23 Jan 2020 19:39:07 +0000 (19:39 +0000)
compiletest: Simplify multi-debugger support

Previous implementation used a single mode type to store various pieces
of otherwise loosely related information:

* Whether debuginfo mode is in use or not.
* Which debuggers should run in general.
* Which debuggers are enabled for particular test case.

The new implementation introduces a separation between those aspects.
There is a single debuginfo mode parametrized by a debugger type.
The debugger detection is performed first and a separate configuration
is created for each detected debugger. The test cases are gathered
independently for each debugger which makes it trivial to implement
support for `ignore` / `only` conditions.

Functional changes:

* A single `debuginfo` entry point (rather than `debuginfo-cdb`, `debuginfo-gdb+lldb`, etc.).
* Debugger name is included in the test name.
* Test outputs are placed in per-debugger directory.
* Fixed spurious hash mismatch. Previously, the config mode would change
  from `DebugInfoGdbLldb` (when collecting tests) to `DebugInfoGdb` or
  `DebugInfoLldb` (when running them) which would affect hash computation.
* PYTHONPATH is additionally included in gdb hash.
* lldb-python and lldb-python-dir are additionally included in lldb hash.

src/bootstrap/test.rs
src/tools/compiletest/src/common.rs
src/tools/compiletest/src/header.rs
src/tools/compiletest/src/main.rs
src/tools/compiletest/src/runtest.rs

index 10e07489e1212ce76f804a177b1fa8cc5c7ee8cf..a186c16f1aa71aac84f3f5c80abd46a39fa7f637 100644 (file)
@@ -957,14 +957,6 @@ fn run(self, builder: &Builder<'_>) {
         }
 
         if suite == "debuginfo" {
-            let msvc = builder.config.build.contains("msvc");
-            if mode == "debuginfo" {
-                return builder.ensure(Compiletest {
-                    mode: if msvc { "debuginfo-cdb" } else { "debuginfo-gdb+lldb" },
-                    ..self
-                });
-            }
-
             builder
                 .ensure(dist::DebuggerScripts { sysroot: builder.sysroot(compiler), host: target });
         }
index 01001ff708c79cbc4c9daac78183b4b46498133c..9cc19060cbddc9d60153d00c2f904179e403a5e4 100644 (file)
@@ -14,10 +14,7 @@ pub enum Mode {
     RunFail,
     RunPassValgrind,
     Pretty,
-    DebugInfoCdb,
-    DebugInfoGdbLldb,
-    DebugInfoGdb,
-    DebugInfoLldb,
+    DebugInfo,
     Codegen,
     Rustdoc,
     CodegenUnits,
@@ -32,13 +29,9 @@ pub enum Mode {
 impl Mode {
     pub fn disambiguator(self) -> &'static str {
         // Pretty-printing tests could run concurrently, and if they do,
-        // they need to keep their output segregated. Same is true for debuginfo tests that
-        // can be run on cdb, gdb, and lldb.
+        // they need to keep their output segregated.
         match self {
             Pretty => ".pretty",
-            DebugInfoCdb => ".cdb",
-            DebugInfoGdb => ".gdb",
-            DebugInfoLldb => ".lldb",
             _ => "",
         }
     }
@@ -52,10 +45,7 @@ fn from_str(s: &str) -> Result<Mode, ()> {
             "run-fail" => Ok(RunFail),
             "run-pass-valgrind" => Ok(RunPassValgrind),
             "pretty" => Ok(Pretty),
-            "debuginfo-cdb" => Ok(DebugInfoCdb),
-            "debuginfo-gdb+lldb" => Ok(DebugInfoGdbLldb),
-            "debuginfo-lldb" => Ok(DebugInfoLldb),
-            "debuginfo-gdb" => Ok(DebugInfoGdb),
+            "debuginfo" => Ok(DebugInfo),
             "codegen" => Ok(Codegen),
             "rustdoc" => Ok(Rustdoc),
             "codegen-units" => Ok(CodegenUnits),
@@ -77,10 +67,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             RunFail => "run-fail",
             RunPassValgrind => "run-pass-valgrind",
             Pretty => "pretty",
-            DebugInfoCdb => "debuginfo-cdb",
-            DebugInfoGdbLldb => "debuginfo-gdb+lldb",
-            DebugInfoGdb => "debuginfo-gdb",
-            DebugInfoLldb => "debuginfo-lldb",
+            DebugInfo => "debuginfo",
             Codegen => "codegen",
             Rustdoc => "rustdoc",
             CodegenUnits => "codegen-units",
@@ -155,6 +142,29 @@ pub fn parse(s: String) -> CompareMode {
     }
 }
 
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum Debugger {
+    Cdb,
+    Gdb,
+    Lldb,
+}
+
+impl Debugger {
+    fn to_str(&self) -> &'static str {
+        match self {
+            Debugger::Cdb => "cdb",
+            Debugger::Gdb => "gdb",
+            Debugger::Lldb => "lldb",
+        }
+    }
+}
+
+impl fmt::Display for Debugger {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(self.to_str(), f)
+    }
+}
+
 /// Configuration for compiletest
 #[derive(Clone)]
 pub struct Config {
@@ -208,6 +218,9 @@ pub struct Config {
     /// The test mode, compile-fail, run-fail, ui
     pub mode: Mode,
 
+    /// The debugger to use in debuginfo mode. Unset otherwise.
+    pub debugger: Option<Debugger>,
+
     /// Run ignored tests
     pub run_ignored: bool,
 
@@ -362,9 +375,11 @@ pub fn output_testname_unique(
     revision: Option<&str>,
 ) -> PathBuf {
     let mode = config.compare_mode.as_ref().map_or("", |m| m.to_str());
+    let debugger = config.debugger.as_ref().map_or("", |m| m.to_str());
     PathBuf::from(&testpaths.file.file_stem().unwrap())
         .with_extra_extension(revision.unwrap_or(""))
         .with_extra_extension(mode)
+        .with_extra_extension(debugger)
 }
 
 /// Absolute path to the directory where all output for the given
index 691b8d3ccfd39c28e4862de975386f77c6e6e76c..34f9ac037b4b836e807f635ab5f6e654810a878b 100644 (file)
@@ -6,52 +6,13 @@
 
 use log::*;
 
-use crate::common::{self, CompareMode, Config, FailMode, Mode, PassMode};
+use crate::common::{CompareMode, Config, Debugger, FailMode, Mode, PassMode};
 use crate::extract_gdb_version;
 use crate::util;
 
 #[cfg(test)]
 mod tests;
 
-/// Whether to ignore the test.
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub enum Ignore {
-    /// Runs it.
-    Run,
-    /// Ignore it totally.
-    Ignore,
-    /// Ignore only the gdb test, but run the lldb test.
-    IgnoreGdb,
-    /// Ignore only the lldb test, but run the gdb test.
-    IgnoreLldb,
-}
-
-impl Ignore {
-    pub fn can_run_gdb(&self) -> bool {
-        *self == Ignore::Run || *self == Ignore::IgnoreLldb
-    }
-
-    pub fn can_run_lldb(&self) -> bool {
-        *self == Ignore::Run || *self == Ignore::IgnoreGdb
-    }
-
-    pub fn no_gdb(&self) -> Ignore {
-        match *self {
-            Ignore::Run => Ignore::IgnoreGdb,
-            Ignore::IgnoreGdb => Ignore::IgnoreGdb,
-            _ => Ignore::Ignore,
-        }
-    }
-
-    pub fn no_lldb(&self) -> Ignore {
-        match *self {
-            Ignore::Run => Ignore::IgnoreLldb,
-            Ignore::IgnoreLldb => Ignore::IgnoreLldb,
-            _ => Ignore::Ignore,
-        }
-    }
-}
-
 /// The result of parse_cfg_name_directive.
 #[derive(Clone, Copy, PartialEq, Debug)]
 enum ParsedNameDirective {
@@ -59,16 +20,12 @@ enum ParsedNameDirective {
     NoMatch,
     /// Match.
     Match,
-    /// Mode was DebugInfoGdbLldb and this matched gdb.
-    MatchGdb,
-    /// Mode was DebugInfoGdbLldb and this matched lldb.
-    MatchLldb,
 }
 
 /// Properties which must be known very early, before actually running
 /// the test.
 pub struct EarlyProps {
-    pub ignore: Ignore,
+    pub ignore: bool,
     pub should_fail: bool,
     pub aux: Vec<String>,
     pub aux_crate: Vec<(String, String)>,
@@ -78,84 +35,61 @@ pub struct EarlyProps {
 impl EarlyProps {
     pub fn from_file(config: &Config, testfile: &Path) -> Self {
         let mut props = EarlyProps {
-            ignore: Ignore::Run,
+            ignore: false,
             should_fail: false,
             aux: Vec::new(),
             aux_crate: Vec::new(),
             revisions: vec![],
         };
 
-        if config.mode == common::DebugInfoGdbLldb {
-            if config.lldb_python_dir.is_none() {
-                props.ignore = props.ignore.no_lldb();
-            }
-            if config.gdb_version.is_none() {
-                props.ignore = props.ignore.no_gdb();
-            }
-        } else if config.mode == common::DebugInfoCdb {
-            if config.cdb.is_none() {
-                props.ignore = Ignore::Ignore;
-            }
-        }
-
         let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some();
         let rustc_has_sanitizer_support = env::var_os("RUSTC_SANITIZER_SUPPORT").is_some();
 
         iter_header(testfile, None, &mut |ln| {
             // we should check if any only-<platform> exists and if it exists
             // and does not matches the current platform, skip the test
-            if props.ignore != Ignore::Ignore {
+            if !props.ignore {
                 props.ignore = match config.parse_cfg_name_directive(ln, "ignore") {
-                    ParsedNameDirective::Match => Ignore::Ignore,
+                    ParsedNameDirective::Match => true,
                     ParsedNameDirective::NoMatch => props.ignore,
-                    ParsedNameDirective::MatchGdb => props.ignore.no_gdb(),
-                    ParsedNameDirective::MatchLldb => props.ignore.no_lldb(),
                 };
 
                 if config.has_cfg_prefix(ln, "only") {
                     props.ignore = match config.parse_cfg_name_directive(ln, "only") {
                         ParsedNameDirective::Match => props.ignore,
-                        ParsedNameDirective::NoMatch => Ignore::Ignore,
-                        ParsedNameDirective::MatchLldb => props.ignore.no_gdb(),
-                        ParsedNameDirective::MatchGdb => props.ignore.no_lldb(),
+                        ParsedNameDirective::NoMatch => true,
                     };
                 }
 
                 if ignore_llvm(config, ln) {
-                    props.ignore = Ignore::Ignore;
+                    props.ignore = true;
                 }
 
                 if config.run_clang_based_tests_with.is_none()
                     && config.parse_needs_matching_clang(ln)
                 {
-                    props.ignore = Ignore::Ignore;
+                    props.ignore = true;
                 }
 
                 if !rustc_has_profiler_support && config.parse_needs_profiler_support(ln) {
-                    props.ignore = Ignore::Ignore;
+                    props.ignore = true;
                 }
 
                 if !rustc_has_sanitizer_support && config.parse_needs_sanitizer_support(ln) {
-                    props.ignore = Ignore::Ignore;
+                    props.ignore = true;
                 }
 
                 if config.target == "wasm32-unknown-unknown" && config.parse_check_run_results(ln) {
-                    props.ignore = Ignore::Ignore;
+                    props.ignore = true;
                 }
-            }
 
-            if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoGdbLldb)
-                && props.ignore.can_run_gdb()
-                && ignore_gdb(config, ln)
-            {
-                props.ignore = props.ignore.no_gdb();
-            }
+                if config.debugger == Some(Debugger::Gdb) && ignore_gdb(config, ln) {
+                    props.ignore = true;
+                }
 
-            if (config.mode == common::DebugInfoLldb || config.mode == common::DebugInfoGdbLldb)
-                && props.ignore.can_run_lldb()
-                && ignore_lldb(config, ln)
-            {
-                props.ignore = props.ignore.no_lldb();
+                if config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln) {
+                    props.ignore = true;
+                }
             }
 
             if let Some(s) = config.parse_aux_build(ln) {
@@ -881,70 +815,37 @@ fn parse_needs_sanitizer_support(&self, line: &str) -> bool {
     /// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86`
     /// or `normalize-stderr-32bit`.
     fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> ParsedNameDirective {
-        if line.starts_with(prefix) && line.as_bytes().get(prefix.len()) == Some(&b'-') {
-            let name = line[prefix.len() + 1..].split(&[':', ' '][..]).next().unwrap();
-
-            if name == "test" ||
-                &self.target == name ||                             // triple
-                util::matches_os(&self.target, name) ||             // target
-                util::matches_env(&self.target, name) ||            // env
-                name == util::get_arch(&self.target) ||             // architecture
-                name == util::get_pointer_width(&self.target) ||    // pointer width
-                name == self.stage_id.split('-').next().unwrap() || // stage
-                (self.target != self.host && name == "cross-compile") ||
-                match self.compare_mode {
-                    Some(CompareMode::Nll) => name == "compare-mode-nll",
-                    Some(CompareMode::Polonius) => name == "compare-mode-polonius",
-                    None => false,
-                } ||
-                (cfg!(debug_assertions) && name == "debug")
-            {
-                ParsedNameDirective::Match
-            } else {
-                match self.mode {
-                    common::DebugInfoGdbLldb => {
-                        if name == "gdb" {
-                            ParsedNameDirective::MatchGdb
-                        } else if name == "lldb" {
-                            ParsedNameDirective::MatchLldb
-                        } else {
-                            ParsedNameDirective::NoMatch
-                        }
-                    }
-                    common::DebugInfoCdb => {
-                        if name == "cdb" {
-                            ParsedNameDirective::Match
-                        } else {
-                            ParsedNameDirective::NoMatch
-                        }
-                    }
-                    common::DebugInfoGdb => {
-                        if name == "gdb" {
-                            ParsedNameDirective::Match
-                        } else {
-                            ParsedNameDirective::NoMatch
-                        }
-                    }
-                    common::DebugInfoLldb => {
-                        if name == "lldb" {
-                            ParsedNameDirective::Match
-                        } else {
-                            ParsedNameDirective::NoMatch
-                        }
-                    }
-                    common::Pretty => {
-                        if name == "pretty" {
-                            ParsedNameDirective::Match
-                        } else {
-                            ParsedNameDirective::NoMatch
-                        }
-                    }
-                    _ => ParsedNameDirective::NoMatch,
-                }
-            }
-        } else {
-            ParsedNameDirective::NoMatch
+        if !line.as_bytes().starts_with(prefix.as_bytes()) {
+            return ParsedNameDirective::NoMatch;
+        }
+        if line.as_bytes().get(prefix.len()) != Some(&b'-') {
+            return ParsedNameDirective::NoMatch;
         }
+
+        let name = line[prefix.len() + 1..].split(&[':', ' '][..]).next().unwrap();
+
+        let is_match = name == "test" ||
+            &self.target == name ||                             // triple
+            util::matches_os(&self.target, name) ||             // target
+            util::matches_env(&self.target, name) ||            // env
+            name == util::get_arch(&self.target) ||             // architecture
+            name == util::get_pointer_width(&self.target) ||    // pointer width
+            name == self.stage_id.split('-').next().unwrap() || // stage
+            (self.target != self.host && name == "cross-compile") ||
+            match self.compare_mode {
+                Some(CompareMode::Nll) => name == "compare-mode-nll",
+                Some(CompareMode::Polonius) => name == "compare-mode-polonius",
+                None => false,
+            } ||
+            (cfg!(debug_assertions) && name == "debug") ||
+            match self.debugger {
+                Some(Debugger::Cdb) => name == "cdb",
+                Some(Debugger::Gdb) => name == "gdb",
+                Some(Debugger::Lldb) => name == "lldb",
+                None => false,
+            };
+
+        if is_match { ParsedNameDirective::Match } else { ParsedNameDirective::NoMatch }
     }
 
     fn has_cfg_prefix(&self, line: &str, prefix: &str) -> bool {
index 1f0b42d1786c13e03ac9e1566f02d8ac2b849be7..5f8aa01f4fc799f5795d73d0d000da7a19aa5069 100644 (file)
@@ -8,9 +8,7 @@
 extern crate test;
 
 use crate::common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS};
-use crate::common::{CompareMode, PassMode};
-use crate::common::{Config, TestPaths};
-use crate::common::{DebugInfoCdb, DebugInfoGdb, DebugInfoGdbLldb, DebugInfoLldb, Mode, Pretty};
+use crate::common::{CompareMode, Config, Debugger, Mode, PassMode, Pretty, TestPaths};
 use crate::util::logv;
 use env_logger;
 use getopts;
@@ -26,7 +24,7 @@
 use test::ColorConfig;
 use walkdir::WalkDir;
 
-use self::header::{EarlyProps, Ignore};
+use self::header::EarlyProps;
 
 #[cfg(test)]
 mod tests;
@@ -50,7 +48,7 @@ fn main() {
     }
 
     log_config(&config);
-    run_tests(&config);
+    run_tests(config);
 }
 
 pub fn parse_config(args: Vec<String>) -> Config {
@@ -199,6 +197,7 @@ fn make_absolute(path: PathBuf) -> PathBuf {
         build_base: opt_path(matches, "build-base"),
         stage_id: matches.opt_str("stage-id").unwrap(),
         mode: matches.opt_str("mode").unwrap().parse().expect("invalid mode"),
+        debugger: None,
         run_ignored,
         filter: matches.free.first().cloned(),
         filter_exact: matches.opt_present("exact"),
@@ -293,61 +292,7 @@ pub fn opt_str2(maybestr: Option<String>) -> String {
     }
 }
 
-pub fn run_tests(config: &Config) {
-    if config.target.contains("android") {
-        if config.mode == DebugInfoGdb || config.mode == DebugInfoGdbLldb {
-            println!(
-                "{} debug-info test uses tcp 5039 port.\
-                 please reserve it",
-                config.target
-            );
-
-            // android debug-info test uses remote debugger so, we test 1 thread
-            // at once as they're all sharing the same TCP port to communicate
-            // over.
-            //
-            // we should figure out how to lift this restriction! (run them all
-            // on different ports allocated dynamically).
-            env::set_var("RUST_TEST_THREADS", "1");
-        }
-    }
-
-    match config.mode {
-        // Note that we don't need to emit the gdb warning when
-        // DebugInfoGdbLldb, so it is ok to list that here.
-        DebugInfoGdbLldb | DebugInfoLldb => {
-            if let Some(lldb_version) = config.lldb_version.as_ref() {
-                if is_blacklisted_lldb_version(&lldb_version[..]) {
-                    println!(
-                        "WARNING: The used version of LLDB ({}) has a \
-                         known issue that breaks debuginfo tests. See \
-                         issue #32520 for more information. Skipping all \
-                         LLDB-based tests!",
-                        lldb_version
-                    );
-                    return;
-                }
-            }
-
-            // Some older versions of LLDB seem to have problems with multiple
-            // instances running in parallel, so only run one test thread at a
-            // time.
-            env::set_var("RUST_TEST_THREADS", "1");
-        }
-
-        DebugInfoGdb => {
-            if config.remote_test_client.is_some() && !config.target.contains("android") {
-                println!(
-                    "WARNING: debuginfo tests are not available when \
-                     testing with remote"
-                );
-                return;
-            }
-        }
-
-        DebugInfoCdb | _ => { /* proceed */ }
-    }
-
+pub fn run_tests(config: Config) {
     // FIXME(#33435) Avoid spurious failures in codegen-units/partitioning tests.
     if let Mode::CodegenUnits = config.mode {
         let _ = fs::remove_dir_all("tmp/partitioning-tests");
@@ -366,8 +311,6 @@ pub fn run_tests(config: &Config) {
         }
     }
 
-    let opts = test_opts(config);
-    let tests = make_tests(config);
     // sadly osx needs some file descriptor limits raised for running tests in
     // parallel (especially when we have lots and lots of child processes).
     // For context, see #8904
@@ -381,6 +324,25 @@ pub fn run_tests(config: &Config) {
     // Let tests know which target they're running as
     env::set_var("TARGET", &config.target);
 
+    let opts = test_opts(&config);
+
+    let mut configs = Vec::new();
+    if let Mode::DebugInfo = config.mode {
+        // Debugging emscripten code doesn't make sense today
+        if !config.target.contains("emscripten") {
+            configs.extend(configure_cdb(&config));
+            configs.extend(configure_gdb(&config));
+            configs.extend(configure_lldb(&config));
+        }
+    } else {
+        configs.push(config);
+    };
+
+    let mut tests = Vec::new();
+    for c in &configs {
+        make_tests(c, &mut tests);
+    }
+
     let res = test::run_tests_console(&opts, tests);
     match res {
         Ok(true) => {}
@@ -391,6 +353,76 @@ pub fn run_tests(config: &Config) {
     }
 }
 
+fn configure_cdb(config: &Config) -> Option<Config> {
+    if config.cdb.is_none() {
+        return None;
+    }
+
+    Some(Config { debugger: Some(Debugger::Cdb), ..config.clone() })
+}
+
+fn configure_gdb(config: &Config) -> Option<Config> {
+    if config.gdb_version.is_none() {
+        return None;
+    }
+
+    if util::matches_env(&config.target, "msvc") {
+        return None;
+    }
+
+    if config.remote_test_client.is_some() && !config.target.contains("android") {
+        println!(
+            "WARNING: debuginfo tests are not available when \
+             testing with remote"
+        );
+        return None;
+    }
+
+    if config.target.contains("android") {
+        println!(
+            "{} debug-info test uses tcp 5039 port.\
+             please reserve it",
+            config.target
+        );
+
+        // android debug-info test uses remote debugger so, we test 1 thread
+        // at once as they're all sharing the same TCP port to communicate
+        // over.
+        //
+        // we should figure out how to lift this restriction! (run them all
+        // on different ports allocated dynamically).
+        env::set_var("RUST_TEST_THREADS", "1");
+    }
+
+    Some(Config { debugger: Some(Debugger::Gdb), ..config.clone() })
+}
+
+fn configure_lldb(config: &Config) -> Option<Config> {
+    if config.lldb_python_dir.is_none() {
+        return None;
+    }
+
+    if let Some(lldb_version) = config.lldb_version.as_ref() {
+        if is_blacklisted_lldb_version(&lldb_version) {
+            println!(
+                "WARNING: The used version of LLDB ({}) has a \
+                 known issue that breaks debuginfo tests. See \
+                 issue #32520 for more information. Skipping all \
+                 LLDB-based tests!",
+                lldb_version
+            );
+            return None;
+        }
+    }
+
+    // Some older versions of LLDB seem to have problems with multiple
+    // instances running in parallel, so only run one test thread at a
+    // time.
+    env::set_var("RUST_TEST_THREADS", "1");
+
+    Some(Config { debugger: Some(Debugger::Lldb), ..config.clone() })
+}
+
 pub fn test_opts(config: &Config) -> test::TestOpts {
     test::TestOpts {
         exclude_should_panic: false,
@@ -415,20 +447,18 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
     }
 }
 
-pub fn make_tests(config: &Config) -> Vec<test::TestDescAndFn> {
+pub fn make_tests(config: &Config, tests: &mut Vec<test::TestDescAndFn>) {
     debug!("making tests from {:?}", config.src_base.display());
     let inputs = common_inputs_stamp(config);
-    let mut tests = Vec::new();
     collect_tests_from_dir(
         config,
         &config.src_base,
         &config.src_base,
         &PathBuf::new(),
         &inputs,
-        &mut tests,
+        tests,
     )
     .expect(&format!("Could not read tests from {}", config.src_base.display()));
-    tests
 }
 
 /// Returns a stamp constructed from input files common to all test cases.
@@ -570,13 +600,7 @@ fn make_test(config: &Config, testpaths: &TestPaths, inputs: &Stamp) -> Vec<test
     revisions
         .into_iter()
         .map(|revision| {
-            let ignore = early_props.ignore == Ignore::Ignore
-                // Debugging emscripten code doesn't make sense today
-                || ((config.mode == DebugInfoGdbLldb || config.mode == DebugInfoCdb ||
-                     config.mode == DebugInfoGdb || config.mode == DebugInfoLldb)
-                    && config.target.contains("emscripten"))
-                || (config.mode == DebugInfoGdb && !early_props.ignore.can_run_gdb())
-                || (config.mode == DebugInfoLldb && !early_props.ignore.can_run_lldb())
+            let ignore = early_props.ignore
                 // Ignore tests that already run and are up to date with respect to inputs.
                 || is_up_to_date(
                     config,
@@ -593,7 +617,7 @@ fn make_test(config: &Config, testpaths: &TestPaths, inputs: &Stamp) -> Vec<test
                     allow_fail: false,
                     test_type: test::TestType::Unknown,
                 },
-                testfn: make_test_closure(config, early_props.ignore, testpaths, revision),
+                testfn: make_test_closure(config, testpaths, revision),
             }
         })
         .collect()
@@ -686,13 +710,19 @@ fn make_test_name(
     let path = PathBuf::from(config.src_base.file_name().unwrap())
         .join(&testpaths.relative_dir)
         .join(&testpaths.file.file_name().unwrap());
+    let debugger = match config.debugger {
+        Some(d) => format!("-{}", d),
+        None => String::new(),
+    };
     let mode_suffix = match config.compare_mode {
         Some(ref mode) => format!(" ({})", mode.to_str()),
         None => String::new(),
     };
+
     test::DynTestName(format!(
-        "[{}{}] {}{}",
+        "[{}{}{}] {}{}",
         config.mode,
+        debugger,
         mode_suffix,
         path.display(),
         revision.map_or("".to_string(), |rev| format!("#{}", rev))
@@ -701,21 +731,10 @@ fn make_test_name(
 
 fn make_test_closure(
     config: &Config,
-    ignore: Ignore,
     testpaths: &TestPaths,
     revision: Option<&String>,
 ) -> test::TestFn {
-    let mut config = config.clone();
-    if config.mode == DebugInfoGdbLldb {
-        // If both gdb and lldb were ignored, then the test as a whole
-        // would be ignored.
-        if !ignore.can_run_gdb() {
-            config.mode = DebugInfoLldb;
-        } else if !ignore.can_run_lldb() {
-            config.mode = DebugInfoGdb;
-        }
-    }
-
+    let config = config.clone();
     let testpaths = testpaths.clone();
     let revision = revision.cloned();
     test::DynTestFn(Box::new(move || {
index 3a114a0b71517de80c20bcb2b7133e0e4167dbaf..d1ee60d74e7e28a35f791cdb9304529b9aa30472 100644 (file)
@@ -3,11 +3,10 @@
 use crate::common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT};
 use crate::common::{output_base_dir, output_base_name, output_testname_unique};
 use crate::common::{Assembly, Incremental, JsDocTest, MirOpt, RunMake, Ui};
-use crate::common::{Codegen, CodegenUnits, Rustdoc};
+use crate::common::{Codegen, CodegenUnits, DebugInfo, Debugger, Rustdoc};
 use crate::common::{CompareMode, FailMode, PassMode};
 use crate::common::{CompileFail, Pretty, RunFail, RunPassValgrind};
 use crate::common::{Config, TestPaths};
-use crate::common::{DebugInfoCdb, DebugInfoGdb, DebugInfoGdbLldb, DebugInfoLldb};
 use crate::common::{UI_RUN_STDERR, UI_RUN_STDOUT};
 use crate::errors::{self, Error, ErrorKind};
 use crate::header::TestProps;
@@ -192,7 +191,7 @@ pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
 
         _ => {
             // android has its own gdb handling
-            if config.mode == DebugInfoGdb && config.gdb.is_none() {
+            if config.debugger == Some(Debugger::Gdb) && config.gdb.is_none() {
                 panic!("gdb not available but debuginfo gdb debuginfo test requested");
             }
         }
@@ -234,21 +233,25 @@ pub fn compute_stamp_hash(config: &Config) -> String {
     let mut hash = DefaultHasher::new();
     config.stage_id.hash(&mut hash);
 
-    if config.mode == DebugInfoCdb {
-        config.cdb.hash(&mut hash);
-    }
+    match config.debugger {
+        Some(Debugger::Cdb) => {
+            config.cdb.hash(&mut hash);
+        }
 
-    if config.mode == DebugInfoGdb || config.mode == DebugInfoGdbLldb {
-        match config.gdb {
-            None => env::var_os("PATH").hash(&mut hash),
-            Some(ref s) if s.is_empty() => env::var_os("PATH").hash(&mut hash),
-            Some(ref s) => s.hash(&mut hash),
-        };
-    }
+        Some(Debugger::Gdb) => {
+            config.gdb.hash(&mut hash);
+            env::var_os("PATH").hash(&mut hash);
+            env::var_os("PYTHONPATH").hash(&mut hash);
+        }
 
-    if config.mode == DebugInfoLldb || config.mode == DebugInfoGdbLldb {
-        env::var_os("PATH").hash(&mut hash);
-        env::var_os("PYTHONPATH").hash(&mut hash);
+        Some(Debugger::Lldb) => {
+            config.lldb_python.hash(&mut hash);
+            config.lldb_python_dir.hash(&mut hash);
+            env::var_os("PATH").hash(&mut hash);
+            env::var_os("PYTHONPATH").hash(&mut hash);
+        }
+
+        None => {}
     }
 
     if let Ui = config.mode {
@@ -309,13 +312,7 @@ fn run_revision(&self) {
             RunFail => self.run_rfail_test(),
             RunPassValgrind => self.run_valgrind_test(),
             Pretty => self.run_pretty_test(),
-            DebugInfoGdbLldb => {
-                self.run_debuginfo_gdb_test();
-                self.run_debuginfo_lldb_test();
-            }
-            DebugInfoCdb => self.run_debuginfo_cdb_test(),
-            DebugInfoGdb => self.run_debuginfo_gdb_test(),
-            DebugInfoLldb => self.run_debuginfo_lldb_test(),
+            DebugInfo => self.run_debuginfo_test(),
             Codegen => self.run_codegen_test(),
             Rustdoc => self.run_rustdoc_test(),
             CodegenUnits => self.run_codegen_units_test(),
@@ -680,13 +677,20 @@ fn typecheck_source(&self, src: String) -> ProcRes {
         self.compose_and_run_compiler(rustc, Some(src))
     }
 
+    fn run_debuginfo_test(&self) {
+        match self.config.debugger.unwrap() {
+            Debugger::Cdb => self.run_debuginfo_cdb_test(),
+            Debugger::Gdb => self.run_debuginfo_gdb_test(),
+            Debugger::Lldb => self.run_debuginfo_lldb_test(),
+        }
+    }
+
     fn run_debuginfo_cdb_test(&self) {
         assert!(self.revision.is_none(), "revisions not relevant here");
 
         let config = Config {
             target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
             host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
-            mode: DebugInfoCdb,
             ..self.config.clone()
         };
 
@@ -765,7 +769,6 @@ fn run_debuginfo_gdb_test(&self) {
         let config = Config {
             target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
             host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
-            mode: DebugInfoGdb,
             ..self.config.clone()
         };
 
@@ -999,7 +1002,6 @@ fn run_debuginfo_lldb_test(&self) {
         let config = Config {
             target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
             host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
-            mode: DebugInfoLldb,
             ..self.config.clone()
         };
 
@@ -1887,8 +1889,8 @@ fn make_compile_args(
 
                 rustc.arg(dir_opt);
             }
-            RunFail | RunPassValgrind | Pretty | DebugInfoCdb | DebugInfoGdbLldb | DebugInfoGdb
-            | DebugInfoLldb | Codegen | Rustdoc | RunMake | CodegenUnits | JsDocTest | Assembly => {
+            RunFail | RunPassValgrind | Pretty | DebugInfo | Codegen | Rustdoc | RunMake
+            | CodegenUnits | JsDocTest | Assembly => {
                 // do not use JSON output
             }
         }