Skip to content

Miri subtree update #141860

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 55 commits into from
Jun 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
17b9213
Implement file cloning on Windows
CraftSpider May 22, 2025
5f3242c
Preparing for merge from rustc
May 23, 2025
98b6d3a
Merge from rustc
May 23, 2025
fa5a507
Merge pull request #4345 from rust-lang/rustup-2025-05-23
RalfJung May 23, 2025
5d5fb18
./miri bench: sort results alphabetically
RalfJung May 23, 2025
853bcea
Merge pull request #4346 from RalfJung/bench
RalfJung May 23, 2025
24d9503
many-seeds tests have become a lot faster thanks to multithreading
RalfJung May 23, 2025
20236c6
test some aarch64 windows targets
RalfJung May 23, 2025
d4d0216
Merge pull request #4347 from RalfJung/ci
RalfJung May 23, 2025
4bbcb47
fix zulip topic URL
RalfJung May 24, 2025
8a79110
Merge pull request #4348 from RalfJung/urlfix
RalfJung May 24, 2025
5c65c35
Preparing for merge from rustc
May 25, 2025
da39cbe
Merge from rustc
May 25, 2025
f25ec48
fmt
May 25, 2025
0e5a162
Merge pull request #4349 from rust-lang/rustup-2025-05-25
RalfJung May 25, 2025
aa94ac1
Preparing for merge from rustc
May 27, 2025
1c73fb9
Merge from rustc
May 27, 2025
bf0aab9
fmt
May 27, 2025
86d0399
pacify clippy
RalfJung May 27, 2025
467591f
Merge pull request #4350 from rust-lang/rustup-2025-05-27
RalfJung May 27, 2025
9aad009
Support F_GETFL and F_SETFL for fcntl
tiif Feb 20, 2025
cbdc930
Merge pull request #4212 from tiif/setfl
RalfJung May 27, 2025
d7c62a0
attempt to fix squash on Windows
RalfJung May 27, 2025
9d9206c
Preparing for merge from rustc
May 28, 2025
15f0fb0
Merge from rustc
May 28, 2025
98485a8
Merge pull request #4351 from RalfJung/squash-win
RalfJung May 28, 2025
bb976bc
Merge pull request #4353 from rust-lang/rustup-2025-05-28
RalfJung May 28, 2025
0fdc38e
Merge pull request #4344 from CraftSpider/windows-file-clone
oli-obk May 28, 2025
6b8a922
fix comment in before_stack_pop
RalfJung May 28, 2025
5a38c32
Merge pull request #4354 from RalfJung/before_stack_pop
RalfJung May 28, 2025
c9addbe
Preparing for merge from rustc
RalfJung May 29, 2025
1b6a290
Merge from rustc
RalfJung May 29, 2025
af48d42
Merge pull request #4355 from RalfJung/rustup
RalfJung May 29, 2025
268440a
add separate allocator for MiriMachine
nia-e May 27, 2025
47e24f0
some refactoring of the allocator
RalfJung May 29, 2025
9164512
Merge pull request #4343 from nia-e/discrete-allocator
RalfJung May 29, 2025
ecc006f
Change diagnostic wording
tiif May 30, 2025
261e444
Merge pull request #4358 from tiif/remove_msg
RalfJung May 30, 2025
089acfa
Track permissions on the byte-level
Apr 18, 2025
2107793
Use "accessed" instead of "initialized" in `LocationState`
May 30, 2025
12300f5
Merge pull request #4314 from yoctocell/fine-grained-tracking
RalfJung May 30, 2025
3e126f2
cargo-miri: recognize --verbose alongside -v
RalfJung May 30, 2025
8c0f859
Merge pull request #4359 from RalfJung/cargo-miri-verbose
RalfJung May 30, 2025
34cdfb7
Preparing for merge from rustc
May 31, 2025
449ec7b
Merge from rustc
May 31, 2025
49a99cb
Merge pull request #4360 from rust-lang/rustup-2025-05-31
RalfJung May 31, 2025
669ebca
accidentally committed file
nia-e May 31, 2025
c37010f
Merge pull request #4361 from nia-e/remove-oopsie
RalfJung May 31, 2025
de289e4
Preparing for merge from rustc
Jun 1, 2025
2150180
Merge from rustc
Jun 1, 2025
af0829b
Merge pull request #4364 from rust-lang/rustup-2025-06-01
saethlin Jun 1, 2025
9f8e157
Fix tokio/file-io.rs test relying on `read`/`write` not being short
Noratrieb Jun 1, 2025
4b94f67
Merge pull request #4368 from Noratrieb/write-not-little-but-a-lot-in…
RalfJung Jun 1, 2025
b88cbed
Make sure to sync on file-io.rs tokio test
Noratrieb Jun 1, 2025
0884c68
tweak comment and use a weaker fence
RalfJung Jun 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/tools/miri/cargo-miri/src/phases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
"`cargo miri` supports the following subcommands: `run`, `test`, `nextest`, `clean`, and `setup`."
),
};
let verbose = num_arg_flag("-v");
let verbose = num_arg_flag("-v") + num_arg_flag("--verbose");
let quiet = has_arg_flag("-q") || has_arg_flag("--quiet");

// Determine the involved architectures.
Expand Down
17 changes: 9 additions & 8 deletions src/tools/miri/ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,12 @@ case $HOST_TARGET in
# Host
GC_STRESS=1 MIR_OPT=1 MANY_SEEDS=64 TEST_BENCH=1 CARGO_MIRI_ENV=1 run_tests
# Extra tier 1
# With reduced many-seed count to avoid spending too much time on that.
# (All OSes and ABIs are run with 64 seeds at least once though via the macOS runner.)
MANY_SEEDS=16 TEST_TARGET=i686-unknown-linux-gnu run_tests
MANY_SEEDS=16 TEST_TARGET=aarch64-unknown-linux-gnu run_tests
MANY_SEEDS=16 TEST_TARGET=x86_64-apple-darwin run_tests
MANY_SEEDS=16 TEST_TARGET=x86_64-pc-windows-gnu run_tests
MANY_SEEDS=64 TEST_TARGET=i686-unknown-linux-gnu run_tests
MANY_SEEDS=64 TEST_TARGET=aarch64-unknown-linux-gnu run_tests
MANY_SEEDS=64 TEST_TARGET=x86_64-apple-darwin run_tests
MANY_SEEDS=64 TEST_TARGET=x86_64-pc-windows-gnu run_tests
# Extra tier 1 candidate
MANY_SEEDS=64 TEST_TARGET=aarch64-pc-windows-msvc run_tests
;;
aarch64-apple-darwin)
# Host
Expand All @@ -156,7 +156,8 @@ case $HOST_TARGET in
MANY_SEEDS=64 TEST_TARGET=i686-pc-windows-gnu run_tests
MANY_SEEDS=64 TEST_TARGET=x86_64-pc-windows-msvc CARGO_MIRI_ENV=1 run_tests
# Extra tier 2
MANY_SEEDS=16 TEST_TARGET=arm-unknown-linux-gnueabi run_tests
MANY_SEEDS=16 TEST_TARGET=arm-unknown-linux-gnueabi run_tests # 32bit ARM
MANY_SEEDS=16 TEST_TARGET=aarch64-pc-windows-gnullvm run_tests # gnullvm ABI
MANY_SEEDS=16 TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture of choice
# Not officially supported tier 2
MANY_SEEDS=16 TEST_TARGET=mips-unknown-linux-gnu run_tests # a 32bit big-endian target, and also a target without 64bit atomics
Expand All @@ -178,7 +179,7 @@ case $HOST_TARGET in
# Host
# Without GC_STRESS and with reduced many-seeds count as this is the slowest runner.
# (The macOS runner checks windows-msvc with full many-seeds count.)
MIR_OPT=1 MANY_SEEDS=16 TEST_BENCH=1 run_tests
MIR_OPT=1 MANY_SEEDS=64 TEST_BENCH=1 run_tests
# Extra tier 1
# We really want to ensure a Linux target works on a Windows host,
# and a 64bit target works on a 32bit host.
Expand Down
49 changes: 37 additions & 12 deletions src/tools/miri/miri-script/src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::collections::BTreeMap;
use std::ffi::{OsStr, OsString};
use std::fmt::Write as _;
use std::fs::{self, File};
Expand Down Expand Up @@ -404,7 +404,28 @@ impl Command {
// We want to forward the host stdin so apparently we cannot use `cmd!`.
let mut cmd = process::Command::new("git");
cmd.arg("rebase").arg(&base).arg("--interactive");
cmd.env("GIT_SEQUENCE_EDITOR", env::current_exe()?);
let current_exe = {
if cfg!(windows) {
// Apparently git-for-Windows gets confused by backslashes if we just use
// `current_exe()` here. So replace them by forward slashes if this is not a "magic"
// path starting with "\\". This is clearly a git bug but we work around it here.
// Also see <https://github.com/rust-lang/miri/issues/4340>.
let bin = env::current_exe()?;
match bin.into_os_string().into_string() {
Err(not_utf8) => not_utf8.into(), // :shrug:
Ok(str) => {
if str.starts_with(r"\\") {
str.into() // don't touch these magic paths, they must use backslashes
} else {
str.replace('\\', "/").into()
}
}
}
} else {
env::current_exe()?
}
};
cmd.env("GIT_SEQUENCE_EDITOR", current_exe);
cmd.env("MIRI_SCRIPT_IS_GIT_SEQUENCE_EDITOR", "1");
cmd.current_dir(sh.current_dir());
let result = cmd.status()?;
Expand Down Expand Up @@ -489,7 +510,9 @@ impl Command {
sh.read_dir(benches_dir)?
.into_iter()
.filter(|path| path.is_dir())
.map(|path| path.into_os_string().into_string().unwrap())
// Only keep the basename: that matches the usage with a manual bench list,
// and it ensure the path concatenations below work as intended.
.map(|path| path.file_name().unwrap().to_owned().into_string().unwrap())
.collect()
} else {
benches.into_iter().collect()
Expand Down Expand Up @@ -530,14 +553,16 @@ impl Command {
stddev: f64,
}

let gather_results = || -> Result<HashMap<&str, BenchResult>> {
let gather_results = || -> Result<BTreeMap<&str, BenchResult>> {
let baseline_temp_dir = results_json_dir.unwrap();
let mut results = HashMap::new();
let mut results = BTreeMap::new();
for bench in &benches {
let result = File::open(path!(baseline_temp_dir / format!("{bench}.bench.json")))?;
let mut result: serde_json::Value =
serde_json::from_reader(BufReader::new(result))?;
let result: BenchResult = serde_json::from_value(result["results"][0].take())?;
let result = File::open(path!(baseline_temp_dir / format!("{bench}.bench.json")))
.context("failed to read hyperfine JSON")?;
let mut result: serde_json::Value = serde_json::from_reader(BufReader::new(result))
.context("failed to parse hyperfine JSON")?;
let result: BenchResult = serde_json::from_value(result["results"][0].take())
.context("failed to interpret hyperfine JSON")?;
results.insert(bench as &str, result);
}
Ok(results)
Expand All @@ -549,15 +574,15 @@ impl Command {
serde_json::to_writer_pretty(BufWriter::new(baseline), &results)?;
} else if let Some(baseline_file) = load_baseline {
let new_results = gather_results()?;
let baseline_results: HashMap<String, BenchResult> = {
let baseline_results: BTreeMap<String, BenchResult> = {
let f = File::open(baseline_file)?;
serde_json::from_reader(BufReader::new(f))?
};
println!(
"Comparison with baseline (relative speed, lower is better for the new results):"
);
for (bench, new_result) in new_results.iter() {
let Some(baseline_result) = baseline_results.get(*bench) else { continue };
for (bench, new_result) in new_results {
let Some(baseline_result) = baseline_results.get(bench) else { continue };

// Compare results (inspired by hyperfine)
let ratio = new_result.mean / baseline_result.mean;
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2b96ddca1272960623e41829439df8dae82d20af
337c11e5932275e7d450c1f2e26f289f0ddfa717
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
use std::alloc::Layout;
use std::borrow::Cow;
use std::{alloc, slice};
#[cfg(target_os = "linux")]
use std::{cell::RefCell, rc::Rc};

use rustc_abi::{Align, Size};
use rustc_middle::mir::interpret::AllocBytes;

#[cfg(target_os = "linux")]
use crate::alloc::isolated_alloc::IsolatedAlloc;
use crate::helpers::ToU64 as _;

#[derive(Clone, Debug)]
pub enum MiriAllocParams {
Global,
#[cfg(target_os = "linux")]
Isolated(Rc<RefCell<IsolatedAlloc>>),
}

/// Allocation bytes that explicitly handle the layout of the data they're storing.
/// This is necessary to interface with native code that accesses the program store in Miri.
#[derive(Debug)]
Expand All @@ -18,13 +29,16 @@ pub struct MiriAllocBytes {
/// * If `self.layout.size() == 0`, then `self.ptr` was allocated with the equivalent layout with size 1.
/// * Otherwise, `self.ptr` points to memory allocated with `self.layout`.
ptr: *mut u8,
/// Whether this instance of `MiriAllocBytes` had its allocation created by calling `alloc::alloc()`
/// (`Global`) or the discrete allocator (`Isolated`)
params: MiriAllocParams,
}

impl Clone for MiriAllocBytes {
fn clone(&self) -> Self {
let bytes: Cow<'_, [u8]> = Cow::Borrowed(self);
let align = Align::from_bytes(self.layout.align().to_u64()).unwrap();
MiriAllocBytes::from_bytes(bytes, align, ())
MiriAllocBytes::from_bytes(bytes, align, self.params.clone())
}
}

Expand All @@ -37,8 +51,16 @@ impl Drop for MiriAllocBytes {
} else {
self.layout
};

// SAFETY: Invariant, `self.ptr` points to memory allocated with `self.layout`.
unsafe { alloc::dealloc(self.ptr, alloc_layout) }
unsafe {
match self.params.clone() {
MiriAllocParams::Global => alloc::dealloc(self.ptr, alloc_layout),
#[cfg(target_os = "linux")]
MiriAllocParams::Isolated(alloc) =>
alloc.borrow_mut().dealloc(self.ptr, alloc_layout),
}
}
}
}

Expand Down Expand Up @@ -67,35 +89,45 @@ impl MiriAllocBytes {
fn alloc_with(
size: u64,
align: u64,
alloc_fn: impl FnOnce(Layout) -> *mut u8,
params: MiriAllocParams,
alloc_fn: impl FnOnce(Layout, &MiriAllocParams) -> *mut u8,
) -> Result<MiriAllocBytes, ()> {
let size = usize::try_from(size).map_err(|_| ())?;
let align = usize::try_from(align).map_err(|_| ())?;
let layout = Layout::from_size_align(size, align).map_err(|_| ())?;
// When size is 0 we allocate 1 byte anyway, to ensure each allocation has a unique address.
let alloc_layout =
if size == 0 { Layout::from_size_align(1, align).unwrap() } else { layout };
let ptr = alloc_fn(alloc_layout);
let ptr = alloc_fn(alloc_layout, &params);
if ptr.is_null() {
Err(())
} else {
// SAFETY: All `MiriAllocBytes` invariants are fulfilled.
Ok(Self { ptr, layout })
Ok(Self { ptr, layout, params })
}
}
}

impl AllocBytes for MiriAllocBytes {
/// Placeholder!
type AllocParams = ();
type AllocParams = MiriAllocParams;

fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, align: Align, _params: ()) -> Self {
fn from_bytes<'a>(
slice: impl Into<Cow<'a, [u8]>>,
align: Align,
params: MiriAllocParams,
) -> Self {
let slice = slice.into();
let size = slice.len();
let align = align.bytes();
// SAFETY: `alloc_fn` will only be used with `size != 0`.
let alloc_fn = |layout| unsafe { alloc::alloc(layout) };
let alloc_bytes = MiriAllocBytes::alloc_with(size.to_u64(), align, alloc_fn)
let alloc_fn = |layout, params: &MiriAllocParams| unsafe {
match params {
MiriAllocParams::Global => alloc::alloc(layout),
#[cfg(target_os = "linux")]
MiriAllocParams::Isolated(alloc) => alloc.borrow_mut().alloc(layout),
}
};
let alloc_bytes = MiriAllocBytes::alloc_with(size.to_u64(), align, params, alloc_fn)
.unwrap_or_else(|()| {
panic!("Miri ran out of memory: cannot create allocation of {size} bytes")
});
Expand All @@ -105,12 +137,18 @@ impl AllocBytes for MiriAllocBytes {
alloc_bytes
}

fn zeroed(size: Size, align: Align, _params: ()) -> Option<Self> {
fn zeroed(size: Size, align: Align, params: MiriAllocParams) -> Option<Self> {
let size = size.bytes();
let align = align.bytes();
// SAFETY: `alloc_fn` will only be used with `size != 0`.
let alloc_fn = |layout| unsafe { alloc::alloc_zeroed(layout) };
MiriAllocBytes::alloc_with(size, align, alloc_fn).ok()
let alloc_fn = |layout, params: &MiriAllocParams| unsafe {
match params {
MiriAllocParams::Global => alloc::alloc_zeroed(layout),
#[cfg(target_os = "linux")]
MiriAllocParams::Isolated(alloc) => alloc.borrow_mut().alloc_zeroed(layout),
}
};
MiriAllocBytes::alloc_with(size, align, params, alloc_fn).ok()
}

fn as_mut_ptr(&mut self) -> *mut u8 {
Expand Down
Loading
Loading