Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 5ac4746

Browse files
committed
Auto merge of rust-lang#2272 - RalfJung:progress, r=RalfJung
add -Zmiri-report-progress to regularly print a stacktrace of what we are executing Fixes rust-lang/miri#910 The stacktrace is printed every N basic blocks. I picked the default (1 million) to take a few seconds on my machine, but it can be adjusted by the user.
2 parents ab88ba4 + 34be937 commit 5ac4746

File tree

6 files changed

+37
-1
lines changed

6 files changed

+37
-1
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,10 @@ environment variable. We first document the most relevant and most commonly used
292292
* `-Zmiri-preemption-rate` configures the probability that at the end of a basic block, the active
293293
thread will be preempted. The default is `0.01` (i.e., 1%). Setting this to `0` disables
294294
preemption.
295+
* `-Zmiri-report-progress` makes Miri print the current stacktrace every now and then, so you can
296+
tell what it is doing when a program just keeps running. You can customize how frequently the
297+
report is printed via `-Zmiri-report-progress=<blocks>`, which prints the report every N basic
298+
blocks.
295299
* `-Zmiri-seed=<hex>` configures the seed of the RNG that Miri uses to resolve non-determinism. This
296300
RNG is used to pick base addresses for allocations, to determine preemption and failure of
297301
`compare_exchange_weak`, and to control store buffering for weak memory emulation. When isolation

src/bin/miri.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,15 @@ fn main() {
468468
),
469469
};
470470
miri_config.preemption_rate = rate;
471+
} else if arg == "-Zmiri-report-progress" {
472+
// This makes it take a few seconds between progress reports on my laptop.
473+
miri_config.report_progress = Some(1_000_000);
474+
} else if let Some(param) = arg.strip_prefix("-Zmiri-report-progress=") {
475+
let interval = match param.parse::<u32>() {
476+
Ok(i) => i,
477+
Err(err) => panic!("-Zmiri-report-progress requires a `u32`: {}", err),
478+
};
479+
miri_config.report_progress = Some(interval);
471480
} else if let Some(param) = arg.strip_prefix("-Zmiri-measureme=") {
472481
miri_config.measureme_out = Some(param.to_string());
473482
} else if let Some(param) = arg.strip_prefix("-Zmiri-backtrace=") {

src/diagnostics.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ pub enum NonHaltingDiagnostic {
6868
CreatedAlloc(AllocId),
6969
FreedAlloc(AllocId),
7070
RejectedIsolatedOp(String),
71+
ProgressReport,
7172
}
7273

7374
/// Level of Miri specific diagnostics
@@ -465,6 +466,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
465466
FreedAlloc(AllocId(id)) => format!("freed allocation with id {id}"),
466467
RejectedIsolatedOp(ref op) =>
467468
format!("{op} was made to return an error due to isolation"),
469+
ProgressReport =>
470+
format!("progress report: current operation being executed is here"),
468471
};
469472

470473
let (title, diag_level) = match e {

src/eval.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ pub struct MiriConfig {
124124
pub mute_stdout_stderr: bool,
125125
/// The probability of the active thread being preempted at the end of each basic block.
126126
pub preemption_rate: f64,
127+
/// Report the current instruction being executed every N basic blocks.
128+
pub report_progress: Option<u32>,
127129
}
128130

129131
impl Default for MiriConfig {
@@ -154,6 +156,7 @@ impl Default for MiriConfig {
154156
provenance_mode: ProvenanceMode::Legacy,
155157
mute_stdout_stderr: false,
156158
preemption_rate: 0.01, // 1%
159+
report_progress: None,
157160
}
158161
}
159162
}

src/machine.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,11 @@ pub struct Evaluator<'mir, 'tcx> {
333333

334334
/// The probability of the active thread being preempted at the end of each basic block.
335335
pub(crate) preemption_rate: f64,
336+
337+
/// If `Some`, we will report the current stack every N basic blocks.
338+
pub(crate) report_progress: Option<u32>,
339+
/// The number of blocks that passed since the last progress report.
340+
pub(crate) since_progress_report: u32,
336341
}
337342

338343
impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
@@ -390,6 +395,8 @@ impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
390395
mute_stdout_stderr: config.mute_stdout_stderr,
391396
weak_memory: config.weak_memory_emulation,
392397
preemption_rate: config.preemption_rate,
398+
report_progress: config.report_progress,
399+
since_progress_report: 0,
393400
}
394401
}
395402

@@ -862,6 +869,16 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
862869
}
863870

864871
fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
872+
// Possibly report our progress.
873+
if let Some(report_progress) = ecx.machine.report_progress {
874+
if ecx.machine.since_progress_report >= report_progress {
875+
register_diagnostic(NonHaltingDiagnostic::ProgressReport);
876+
ecx.machine.since_progress_report = 0;
877+
}
878+
// Cannot overflow, since it is strictly less than `report_progress`.
879+
ecx.machine.since_progress_report += 1;
880+
}
881+
// These are our preemption points.
865882
ecx.maybe_preempt_active_thread();
866883
Ok(())
867884
}

test-cargo-miri/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn main() {
1616
not_in_miri();
1717
// Cargo calls `miri --print=cfg` to populate the `CARGO_CFG_*` env vars.
1818
// Make sure that the "miri" flag is set.
19-
assert!(env::var_os("CARGO_CFG_MIRI").is_some());
19+
assert!(env::var_os("CARGO_CFG_MIRI").is_some(), "cargo failed to tell us about `--cfg miri`");
2020
println!("cargo:rerun-if-changed=build.rs");
2121
println!("cargo:rerun-if-env-changed=MIRITESTVAR");
2222
println!("cargo:rustc-env=MIRITESTVAR=testval");

0 commit comments

Comments
 (0)