Skip to content

Commit d9d0ef1

Browse files
Rollup merge of #148099 - Zalathar:debuggers, r=jieyouxu
Prepare to move debugger discovery from compiletest to bootstrap For a while I've been wanting to move debugger discovery out of compiletest and into bootstrap, so that bootstrap would be responsible for deciding which debugger to use, and compiletest would faithfully use that debugger with no extra magic (and no horrible config-duplicating hacks). Making that change is complicated, and eventually I had so many intertwined preparatory changes that I split them off into this PR, so that it can be reviewed and tested as a smaller chunk. --- To avoid scope creep, the changes in this PR try to move code as-is as much as possible, even if the moved code could arguably benefit from further cleanups. And in many cases, that code will need to be further overhauled anyway when discovery steps are actually moved out of compiletest.
2 parents c0bbebf + bcfbd74 commit d9d0ef1

File tree

8 files changed

+123
-52
lines changed

8 files changed

+123
-52
lines changed

src/bootstrap/src/core/build_steps/test.rs

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use crate::core::builder::{
2929
};
3030
use crate::core::config::TargetSelection;
3131
use crate::core::config::flags::{Subcommand, get_completion, top_level_help};
32+
use crate::core::debuggers;
3233
use crate::utils::build_stamp::{self, BuildStamp};
3334
use crate::utils::exec::{BootstrapCommand, command};
3435
use crate::utils::helpers::{
@@ -38,8 +39,6 @@ use crate::utils::helpers::{
3839
use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests};
3940
use crate::{CLang, CodegenBackendKind, DocTests, GitRepo, Mode, PathSet, envify};
4041

41-
const ADB_TEST_DIR: &str = "/data/local/tmp/work";
42-
4342
/// Runs `cargo test` on various internal tools used by bootstrap.
4443
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4544
pub struct CrateBootstrap {
@@ -2078,27 +2077,28 @@ Please disable assertions with `rust.debug-assertions = false`.
20782077

20792078
cmd.arg("--python").arg(builder.python());
20802079

2081-
if let Some(ref gdb) = builder.config.gdb {
2082-
cmd.arg("--gdb").arg(gdb);
2083-
}
2084-
2085-
let lldb_exe = builder.config.lldb.clone().unwrap_or_else(|| PathBuf::from("lldb"));
2086-
let lldb_version = command(&lldb_exe)
2087-
.allow_failure()
2088-
.arg("--version")
2089-
.run_capture(builder)
2090-
.stdout_if_ok()
2091-
.and_then(|v| if v.trim().is_empty() { None } else { Some(v) });
2092-
if let Some(ref vers) = lldb_version {
2093-
cmd.arg("--lldb-version").arg(vers);
2094-
let lldb_python_dir = command(&lldb_exe)
2095-
.allow_failure()
2096-
.arg("-P")
2097-
.run_capture_stdout(builder)
2098-
.stdout_if_ok()
2099-
.map(|p| p.lines().next().expect("lldb Python dir not found").to_string());
2100-
if let Some(ref dir) = lldb_python_dir {
2101-
cmd.arg("--lldb-python-dir").arg(dir);
2080+
// FIXME(#148099): Currently we set these Android-related flags in all
2081+
// modes, even though they should only be needed in "debuginfo" mode,
2082+
// because the GDB-discovery code in compiletest currently assumes that
2083+
// `--android-cross-path` is always set for Android targets.
2084+
if let Some(debuggers::Android { adb_path, adb_test_dir, android_cross_path }) =
2085+
debuggers::discover_android(builder, target)
2086+
{
2087+
cmd.arg("--adb-path").arg(adb_path);
2088+
cmd.arg("--adb-test-dir").arg(adb_test_dir);
2089+
cmd.arg("--android-cross-path").arg(android_cross_path);
2090+
}
2091+
2092+
if mode == "debuginfo" {
2093+
if let Some(debuggers::Gdb { gdb }) = debuggers::discover_gdb(builder) {
2094+
cmd.arg("--gdb").arg(gdb);
2095+
}
2096+
2097+
if let Some(debuggers::Lldb { lldb_version, lldb_python_dir }) =
2098+
debuggers::discover_lldb(builder)
2099+
{
2100+
cmd.arg("--lldb-version").arg(lldb_version);
2101+
cmd.arg("--lldb-python-dir").arg(lldb_python_dir);
21022102
}
21032103
}
21042104

@@ -2332,16 +2332,6 @@ Please disable assertions with `rust.debug-assertions = false`.
23322332

23332333
cmd.env("RUST_TEST_TMPDIR", builder.tempdir());
23342334

2335-
cmd.arg("--adb-path").arg("adb");
2336-
cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);
2337-
if target.contains("android") && !builder.config.dry_run() {
2338-
// Assume that cc for this target comes from the android sysroot
2339-
cmd.arg("--android-cross-path")
2340-
.arg(builder.cc(target).parent().unwrap().parent().unwrap());
2341-
} else {
2342-
cmd.arg("--android-cross-path").arg("");
2343-
}
2344-
23452335
if builder.config.cmd.rustfix_coverage() {
23462336
cmd.arg("--rustfix-coverage");
23472337
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use std::path::PathBuf;
2+
3+
use crate::core::builder::Builder;
4+
use crate::core::config::TargetSelection;
5+
6+
pub(crate) struct Android {
7+
pub(crate) adb_path: &'static str,
8+
pub(crate) adb_test_dir: &'static str,
9+
pub(crate) android_cross_path: PathBuf,
10+
}
11+
12+
pub(crate) fn discover_android(builder: &Builder<'_>, target: TargetSelection) -> Option<Android> {
13+
let adb_path = "adb";
14+
// See <https://github.com/rust-lang/rust/pull/102755>.
15+
let adb_test_dir = "/data/local/tmp/work";
16+
17+
let android_cross_path = if target.contains("android") && !builder.config.dry_run() {
18+
builder.cc(target).parent().unwrap().parent().unwrap().to_owned()
19+
} else {
20+
PathBuf::new()
21+
};
22+
23+
Some(Android { adb_path, adb_test_dir, android_cross_path })
24+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use std::path::Path;
2+
3+
use crate::core::builder::Builder;
4+
5+
pub(crate) struct Gdb<'a> {
6+
pub(crate) gdb: &'a Path,
7+
}
8+
9+
pub(crate) fn discover_gdb<'a>(builder: &'a Builder<'_>) -> Option<Gdb<'a>> {
10+
let gdb = builder.config.gdb.as_deref()?;
11+
12+
Some(Gdb { gdb })
13+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use std::path::PathBuf;
2+
3+
use crate::core::builder::Builder;
4+
use crate::utils::exec::command;
5+
6+
pub(crate) struct Lldb {
7+
pub(crate) lldb_version: String,
8+
pub(crate) lldb_python_dir: String,
9+
}
10+
11+
pub(crate) fn discover_lldb(builder: &Builder<'_>) -> Option<Lldb> {
12+
// FIXME(#148361): We probably should not be picking up whatever arbitrary
13+
// lldb happens to be in the user's path, and instead require some kind of
14+
// explicit opt-in or configuration.
15+
let lldb_exe = builder.config.lldb.clone().unwrap_or_else(|| PathBuf::from("lldb"));
16+
17+
let lldb_version = command(&lldb_exe)
18+
.allow_failure()
19+
.arg("--version")
20+
.run_capture(builder)
21+
.stdout_if_ok()
22+
.and_then(|v| if v.trim().is_empty() { None } else { Some(v) })?;
23+
24+
let lldb_python_dir = command(&lldb_exe)
25+
.allow_failure()
26+
.arg("-P")
27+
.run_capture_stdout(builder)
28+
.stdout_if_ok()
29+
.map(|p| p.lines().next().expect("lldb Python dir not found").to_string())?;
30+
31+
Some(Lldb { lldb_version, lldb_python_dir })
32+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//! Code for discovering debuggers and debugger-related configuration, so that
2+
//! it can be passed to compiletest when running debuginfo tests.
3+
4+
pub(crate) use self::android::{Android, discover_android};
5+
pub(crate) use self::gdb::{Gdb, discover_gdb};
6+
pub(crate) use self::lldb::{Lldb, discover_lldb};
7+
8+
mod android;
9+
mod gdb;
10+
mod lldb;

src/bootstrap/src/core/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub(crate) mod build_steps;
22
pub(crate) mod builder;
33
pub(crate) mod config;
4+
pub(crate) mod debuggers;
45
pub(crate) mod download;
56
pub(crate) mod metadata;
67
pub(crate) mod sanity;

src/tools/compiletest/src/debuggers.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -103,22 +103,19 @@ fn find_cdb(target: &str) -> Option<Utf8PathBuf> {
103103
}
104104

105105
/// Returns Path to CDB
106-
pub(crate) fn analyze_cdb(
107-
cdb: Option<String>,
108-
target: &str,
109-
) -> (Option<Utf8PathBuf>, Option<[u16; 4]>) {
106+
pub(crate) fn discover_cdb(cdb: Option<String>, target: &str) -> Option<Utf8PathBuf> {
110107
let cdb = cdb.map(Utf8PathBuf::from).or_else(|| find_cdb(target));
108+
cdb
109+
}
111110

111+
pub(crate) fn query_cdb_version(cdb: &Utf8Path) -> Option<[u16; 4]> {
112112
let mut version = None;
113-
if let Some(cdb) = cdb.as_ref() {
114-
if let Ok(output) = Command::new(cdb).arg("/version").output() {
115-
if let Some(first_line) = String::from_utf8_lossy(&output.stdout).lines().next() {
116-
version = extract_cdb_version(&first_line);
117-
}
113+
if let Ok(output) = Command::new(cdb).arg("/version").output() {
114+
if let Some(first_line) = String::from_utf8_lossy(&output.stdout).lines().next() {
115+
version = extract_cdb_version(&first_line);
118116
}
119117
}
120-
121-
(cdb, version)
118+
version
122119
}
123120

124121
pub(crate) fn extract_cdb_version(full_version_line: &str) -> Option<[u16; 4]> {
@@ -132,12 +129,11 @@ pub(crate) fn extract_cdb_version(full_version_line: &str) -> Option<[u16; 4]> {
132129
Some([major, minor, patch, build])
133130
}
134131

135-
/// Returns (Path to GDB, GDB Version)
136-
pub(crate) fn analyze_gdb(
132+
pub(crate) fn discover_gdb(
137133
gdb: Option<String>,
138134
target: &str,
139135
android_cross_path: &Utf8Path,
140-
) -> (Option<String>, Option<u32>) {
136+
) -> Option<String> {
141137
#[cfg(not(windows))]
142138
const GDB_FALLBACK: &str = "gdb";
143139
#[cfg(windows)]
@@ -159,6 +155,10 @@ pub(crate) fn analyze_gdb(
159155
Some(ref s) => s.to_owned(),
160156
};
161157

158+
Some(gdb)
159+
}
160+
161+
pub(crate) fn query_gdb_version(gdb: &str) -> Option<u32> {
162162
let mut version_line = None;
163163
if let Ok(output) = Command::new(&gdb).arg("--version").output() {
164164
if let Some(first_line) = String::from_utf8_lossy(&output.stdout).lines().next() {
@@ -168,10 +168,10 @@ pub(crate) fn analyze_gdb(
168168

169169
let version = match version_line {
170170
Some(line) => extract_gdb_version(&line),
171-
None => return (None, None),
171+
None => return None,
172172
};
173173

174-
(Some(gdb), version)
174+
version
175175
}
176176

177177
pub(crate) fn extract_gdb_version(full_version_line: &str) -> Option<u32> {

src/tools/compiletest/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,11 @@ fn parse_config(args: Vec<String>) -> Config {
258258
let target = opt_str2(matches.opt_str("target"));
259259
let android_cross_path = opt_path(matches, "android-cross-path");
260260
// FIXME: `cdb_version` is *derived* from cdb, but it's *not* technically a config!
261-
let (cdb, cdb_version) = debuggers::analyze_cdb(matches.opt_str("cdb"), &target);
261+
let cdb = debuggers::discover_cdb(matches.opt_str("cdb"), &target);
262+
let cdb_version = cdb.as_deref().and_then(debuggers::query_cdb_version);
262263
// FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config!
263-
let (gdb, gdb_version) =
264-
debuggers::analyze_gdb(matches.opt_str("gdb"), &target, &android_cross_path);
264+
let gdb = debuggers::discover_gdb(matches.opt_str("gdb"), &target, &android_cross_path);
265+
let gdb_version = gdb.as_deref().and_then(debuggers::query_gdb_version);
265266
// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
266267
let lldb_version =
267268
matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version);

0 commit comments

Comments
 (0)