Skip to content

Commit e8b9383

Browse files
authored
Unrolled build for #145565
Rollup merge of #145565 - Kobzol:bootstrap-ci-print-error, r=jieyouxu Improve context of bootstrap errors in CI Inspired by https://rust-lang.zulipchat.com/#narrow/channel/326414-t-infra.2Fbootstrap/topic/printing.20test.20suite.20name.20by.20default/with/534920583, this PR attempts to improve the context displayed when a bootstrap invocation fails in CI. Since #145261, we now see the latest started step when a failure occurs. However, we can go further. 1) The first commit prints the actual executed bootstrap invocation command arguments when bootstrap ends. Since CI jobs often run multiple bootstrap commands, this makes it easier to figure out which one of them failed (before it was annoying having to search for that in CI logs). Because bootstrap doesn't really use `Result`s much, and most of them time it ends with the `detail_exit` function, which YOLOs `std::process::exit(...)`, I added the print there. 2) Adds `#[track_caller]` to a few bootstrap Cargo builder functions. This makes the log that we print when a command fails more accurate: ``` 2025-08-16T18:18:51.6998201Z Command ... failed ... 2025-08-16T18:18:51.7003653Z Created at: src/bootstrap/src/core/builder/cargo.rs:423:33 2025-08-16T18:18:51.7004032Z Executed at: src/bootstrap/src/core/build_steps/doc.rs:933:26 ``` Before, the `cargo.rs:XYZ` location wasn't very useful. 3) Is the most wild thing (I'll revert if you find it too magical). We store the step stack of the currently active `Builder` instance in a global variable, and when bootstrap exits with a failure, we print the stack, to make it easier to find out what was happening when a failure occurred. We could print an actual captured `Backtrace`, but I think that would be too much information in the common case. We now pass `RUST_BACKTRACE=1` on CI, so if bootstrap actually crashes unexpectedly, we would see the stacktrace. The end of the bootsrap failure log in CI now looks like this now: ``` Bootstrap failed while executing `x build library` ---BOOTSTRAP step stack start--- Assemble { target_compiler: Compiler { stage: 1, host: x86_64-unknown-linux-gnu, forced_compiler: false } } Rustc { target: x86_64-unknown-linux-gnu, build_compiler: Compiler { stage: 0, host: x86_64-unknown-linux-gnu, forced_compiler: false }, crates: [] } ---BOOTSTRAP step stack end--- ``` r? `@jieyouxu`
2 parents b96868f + a1f5bbe commit e8b9383

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

src/bootstrap/src/core/builder/cargo.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ pub struct Cargo {
101101
impl Cargo {
102102
/// Calls [`Builder::cargo`] and [`Cargo::configure_linker`] to prepare an invocation of `cargo`
103103
/// to be run.
104+
#[track_caller]
104105
pub fn new(
105106
builder: &Builder<'_>,
106107
compiler: Compiler,
@@ -139,6 +140,7 @@ impl Cargo {
139140

140141
/// Same as [`Cargo::new`] except this one doesn't configure the linker with
141142
/// [`Cargo::configure_linker`].
143+
#[track_caller]
142144
pub fn new_for_mir_opt_tests(
143145
builder: &Builder<'_>,
144146
compiler: Compiler,
@@ -396,6 +398,7 @@ impl From<Cargo> for BootstrapCommand {
396398

397399
impl Builder<'_> {
398400
/// Like [`Builder::cargo`], but only passes flags that are valid for all commands.
401+
#[track_caller]
399402
pub fn bare_cargo(
400403
&self,
401404
compiler: Compiler,
@@ -480,6 +483,7 @@ impl Builder<'_> {
480483
/// scoped by `mode`'s output directory, it will pass the `--target` flag for the specified
481484
/// `target`, and will be executing the Cargo command `cmd`. `cmd` can be `miri-cmd` for
482485
/// commands to be run with Miri.
486+
#[track_caller]
483487
fn cargo(
484488
&self,
485489
compiler: Compiler,

src/build_helper/src/util.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use std::io::{BufRead, BufReader};
33
use std::path::Path;
44
use std::process::Command;
55

6+
use crate::ci::CiEnv;
7+
68
/// Invokes `build_helper::util::detail_exit` with `cfg!(test)`
79
///
810
/// This is a macro instead of a function so that it uses `cfg(test)` in the *calling* crate, not in build helper.
@@ -20,6 +22,15 @@ pub fn detail_exit(code: i32, is_test: bool) -> ! {
2022
if is_test {
2123
panic!("status code: {code}");
2224
} else {
25+
// If we're in CI, print the current bootstrap invocation command, to make it easier to
26+
// figure out what exactly has failed.
27+
if CiEnv::is_ci() {
28+
// Skip the first argument, as it will be some absolute path to the bootstrap binary.
29+
let bootstrap_args =
30+
std::env::args().skip(1).map(|a| a.to_string()).collect::<Vec<_>>().join(" ");
31+
eprintln!("Bootstrap failed while executing `{bootstrap_args}`");
32+
}
33+
2334
// otherwise, exit with provided status code
2435
std::process::exit(code);
2536
}

0 commit comments

Comments
 (0)