Skip to content

Commit

Permalink
Auto merge of rust-lang#103392 - RalfJung:miri, r=oli-obk
Browse files Browse the repository at this point in the history
update Miri

I had to use a hacked version of josh to create this, so let's be careful with merging this and maybe wait a bit to see if the josh issue becomes more clear. But the history looks good to me, we are not adding duplicates of rustc commits that were previously mirrored to Miri.

Also I want to add some cross-testing of Miri in x.py.
  • Loading branch information
bors committed Oct 25, 2022
2 parents 7749251 + ff0f5b3 commit de0fd42
Show file tree
Hide file tree
Showing 64 changed files with 1,467 additions and 465 deletions.
44 changes: 40 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
RUST_BACKTRACE: 1
HOST_TARGET: ${{ matrix.host_target }}
strategy:
fail-fast: false
matrix:
build: [linux64, macos, win32]
include:
Expand Down Expand Up @@ -61,7 +62,7 @@ jobs:
restore-keys: ${{ runner.os }}-cargo

- name: Install rustup-toolchain-install-master
if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }}
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
shell: bash
run: |
cargo install -f rustup-toolchain-install-master
Expand Down Expand Up @@ -89,11 +90,46 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install required toolchain
# We need a toolchain that can actually build Miri, just a nightly won't do.

# This is exactly duplicated from above. GHA is pretty terrible when it comes
# to avoiding code duplication.

# Cache the global cargo directory, but NOT the local `target` directory which
# we cannot reuse anyway when the nightly changes (and it grows quite large
# over time).
- name: Add cache for cargo
id: cache
uses: actions/cache@v3
with:
path: |
# Taken from <https://doc.rust-lang.org/nightly/cargo/guide/cargo-home.html#caching-the-cargo-home-in-ci>.
~/.cargo/bin
~/.cargo/registry/index
~/.cargo/registry/cache
~/.cargo/git/db
# contains package information of crates installed via `cargo install`.
~/.cargo/.crates.toml
~/.cargo/.crates2.json
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo

- name: Install rustup-toolchain-install-master
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
shell: bash
run: |
cargo install -f rustup-toolchain-install-master
- name: Install "master" toolchain
shell: bash
run: |
cargo install rustup-toolchain-install-master # TODO: cache this?
./rustup-toolchain "" -c clippy
- name: Show Rust version
run: |
rustup show
rustc -Vv
cargo -V
- name: rustfmt
run: ./miri fmt --check
- name: clippy
Expand Down
52 changes: 50 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ MIRI_LOG=rustc_mir::interpret=info,miri::stacked_borrows ./miri run tests/pass/v
In addition, you can set `MIRI_BACKTRACE=1` to get a backtrace of where an
evaluation error was originally raised.

#### UI testing
### UI testing

We use ui-testing in Miri, meaning we generate `.stderr` and `.stdout` files for the output
produced by Miri. You can use `./miri bless` to automatically (re)generate these files when
Expand Down Expand Up @@ -257,7 +257,7 @@ Note: When you are working with a locally built rustc or any other toolchain tha
is not the same as the one in `rust-version`, you should not have `.auto-everything` or
`.auto-toolchain` as that will keep resetting your toolchain.

```
```sh
rm -f .auto-everything .auto-toolchain
```

Expand All @@ -275,3 +275,51 @@ see <https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html>.

With this, you should now have a working development setup! See
[above](#building-and-testing-miri) for how to proceed working on Miri.

## Advanced topic: Syncing with the rustc repo

We use the [`josh` proxy](https://github.com/josh-project/josh) to transmit
changes between the rustc and Miri repositories. For now, a fork of josh needs to be built
from source. This downloads and runs josh:

```sh
git clone https://github.com/RalfJung/josh
cd josh
cargo run --release -p josh-proxy -- --local=$(pwd)/local --remote=https://github.com --no-background
```

### Importing changes from the rustc repo

We assume we start on an up-to-date master branch in the Miri repo.

```sh
# Fetch rustc side of the history. Takes ca 5 min the first time.
# Do NOT change that commit ID, it needs to be exactly this!
git fetch http://localhost:8000/rust-lang/rust.git:at_commit=75dd959a3a40eb5b4574f8d2e23aa6efbeb33573[:prefix=src/tools/miri]:/src/tools/miri.git master
# Include that history into ours.
git merge FETCH_HEAD -m "merge rustc history"
# Update toolchain reference and apply formatting.
./rustup-toolchain HEAD && ./miri fmt
git commit -am "rustup"
```

Now push this to a new branch in your Miri fork, and create a PR. It is worth
running `./miri test` locally in parallel, since the test suite in the Miri repo
is stricter than the one on the rustc side, so some small tweaks might be
needed.

### Exporting changes to the rustc repo

We will use the josh proxy to push to your fork of rustc. You need to make sure
that the master branch of your fork is up-to-date. Also make sure that there
exists no branch called `miri` in your fork. Then run the following in the Miri
repo, assuming we are on an up-to-date master branch:

```sh
# Push the Miri changes to your rustc fork (substitute your github handle for YOUR_NAME).
# Do NOT change that commit ID, it needs to be exactly this!
git push http://localhost:8000/YOUR_NAME/rust.git:at_commit=75dd959a3a40eb5b4574f8d2e23aa6efbeb33573[:prefix=src/tools/miri]:/src/tools/miri.git -o base=master HEAD:miri
```

This will create a new branch in your fork, and the output should include a link
to create a rustc PR that will integrate those changes into the main repository.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,17 @@ smallvec = "1.7"
rustc-workspace-hack = "1.0.0"
measureme = "10.0.0"

[target."cfg(unix)".dependencies]
[target.'cfg(unix)'.dependencies]
libc = "0.2"

[target.'cfg(target_os = "linux")'.dependencies]
libffi = "3.0.0"
libloading = "0.7"

[dev-dependencies]
colored = "2"
ui_test = "0.3.1"
rustc_version = "0.4"
# Features chosen to match those required by env_logger, to avoid rebuilds
regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] }
lazy_static = "1.4.0"
Expand Down
35 changes: 30 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,11 @@ to Miri failing to detect cases of undefined behavior in a program.
* `-Zmiri-retag-fields` changes Stacked Borrows retagging to recurse into fields.
This means that references in fields of structs/enums/tuples/arrays/... are retagged,
and in particular, they are protected when passed as function arguments.
* `-Zmiri-retag-fields=<all|none|scalar>` controls when Stacked Borrows retagging recurses into
fields. `all` means it always recurses (like `-Zmiri-retag-fields`), `none` means it never
recurses (the default), `scalar` means it only recurses for types where we would also emit
`noalias` annotations in the generated LLVM IR (types passed as indivudal scalars or pairs of
scalars).
* `-Zmiri-tag-gc=<blocks>` configures how often the pointer tag garbage collector runs. The default
is to search for and remove unreachable tags once every `10000` basic blocks. Setting this to
`0` disables the garbage collector, which causes some programs to have explosive memory usage
Expand Down Expand Up @@ -435,11 +440,10 @@ Moreover, Miri recognizes some environment variables:
purpose.
* `MIRI_NO_STD` (recognized by `cargo miri` and the test suite) makes sure that the target's
sysroot is built without libstd. This allows testing and running no_std programs.
* `MIRI_BLESS` (recognized by the test suite) overwrite all `stderr` and `stdout` files
instead of checking whether the output matches.
* `MIRI_SKIP_UI_CHECKS` (recognized by the test suite) don't check whether the
`stderr` or `stdout` files match the actual output. Useful for the rustc test suite
which has subtle differences that we don't care about.
* `MIRI_BLESS` (recognized by the test suite and `cargo-miri-test/run-test.py`): overwrite all
`stderr` and `stdout` files instead of checking whether the output matches.
* `MIRI_SKIP_UI_CHECKS` (recognized by the test suite): don't check whether the
`stderr` or `stdout` files match the actual output.

The following environment variables are *internal* and must not be used by
anyone but Miri itself. They are used to communicate between different Miri
Expand Down Expand Up @@ -532,6 +536,27 @@ extern "Rust" {
/// This is internal and unstable and should not be used; we give it here
/// just to be complete.
fn miri_start_panic(payload: *mut u8) -> !;

/// Miri-provided extern function to get the internal unique identifier for the allocation that a pointer
/// points to. This is only useful as an input to `miri_print_stacks`, and it is a separate call because
/// getting a pointer to an allocation at runtime can change the borrow stacks in the allocation.
fn miri_get_alloc_id(ptr: *const ()) -> u64;

/// Miri-provided extern function to print (from the interpreter, not the program) the contents of all
/// borrow stacks in an allocation. The format of what this emits is unstable and may change at any time.
/// In particular, users should be aware that Miri will periodically attempt to garbage collect the
/// contents of all stacks. Callers of this function may wish to pass `-Zmiri-tag-gc=0` to disable the GC.
fn miri_print_stacks(alloc_id: u64);

/// Miri-provided extern function to print (from the interpreter, not the
/// program) the contents of a section of program memory, as bytes. Bytes
/// written using this function will emerge from the interpreter's stdout.
fn miri_write_to_stdout(bytes: &[u8]);

/// Miri-provided extern function to print (from the interpreter, not the
/// program) the contents of a section of program memory, as bytes. Bytes
/// written using this function will emerge from the interpreter's stderr.
fn miri_write_to_stderr(bytes: &[u8]);
}
```

Expand Down
1 change: 1 addition & 0 deletions bench-cargo-miri/serde2/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use serde::Deserialize;
use std::thread;

#[derive(Deserialize)]
#[allow(unused)]
struct DeriveStruct {
buffer: Vec<i16>,
}
Expand Down
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
acb8934fd57b3c2740c4abac0a5728c2c9b1423b
b1ab3b738ac718da74cd4aa0bb7f362d0adbdf84
11 changes: 9 additions & 2 deletions src/bin/miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use rustc_middle::{
};
use rustc_session::{config::CrateType, search_paths::PathKind, CtfeBacktrace};

use miri::{BacktraceStyle, ProvenanceMode};
use miri::{BacktraceStyle, ProvenanceMode, RetagFields};

struct MiriCompilerCalls {
miri_config: miri::MiriConfig,
Expand Down Expand Up @@ -426,7 +426,14 @@ fn main() {
} else if arg == "-Zmiri-mute-stdout-stderr" {
miri_config.mute_stdout_stderr = true;
} else if arg == "-Zmiri-retag-fields" {
miri_config.retag_fields = true;
miri_config.retag_fields = RetagFields::Yes;
} else if let Some(retag_fields) = arg.strip_prefix("-Zmiri-retag-fields=") {
miri_config.retag_fields = match retag_fields {
"all" => RetagFields::Yes,
"none" => RetagFields::No,
"scalar" => RetagFields::OnlyScalar,
_ => show_error!("`-Zmiri-retag-fields` can only be `all`, `none`, or `scalar`"),
};
} else if arg == "-Zmiri-track-raw-pointers" {
eprintln!(
"WARNING: `-Zmiri-track-raw-pointers` has no effect; it is enabled by default"
Expand Down
Loading

0 comments on commit de0fd42

Please sign in to comment.