miri icon indicating copy to clipboard operation
miri copied to clipboard

cargo-miri generates empty .d file, gets confused about multiple crates of the same name when using shared target dir

Open Nemo157 opened this issue 3 years ago • 7 comments

When testing little ideas I very commonly work with a crate foo in different temp directories. If I haven't recently cleaned my shared target-dir then cargo-miri gets confused about whether it needs to rebuild artifacts and uses the wrong binary to test with.

As an example these two commands create two separate crates that should print different things, but cargo miri run in the second crate doesn't do a rebuild and instead runs the binary from the first crate:

> cd $(mktemp -d) && cargo new foo && cd foo && pwd && echo 'fn main() { println!("foo 1"); }' > src/main.rs && cargo miri run
     Created binary (application) `foo` package
/tmp/tmp.mI8gDBgdqJ/foo
Preparing a sysroot for Miri (target: x86_64-unknown-linux-gnu)... done
   Compiling foo v0.1.0 (/tmp/tmp.mI8gDBgdqJ/foo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
     Running `/home/nemo157/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo-miri runner /home/nemo157/.cargo/shared-target/miri/x86_64-unknown-linux-gnu/debug/foo`
foo 1

> cd $(mktemp -d) && cargo new foo && cd foo && pwd && echo 'fn main() { println!("foo 2"); }' > src/main.rs && cargo miri run
     Created binary (application) `foo` package
/tmp/tmp.IHFWjzhAmy/foo
Preparing a sysroot for Miri (target: x86_64-unknown-linux-gnu)... done
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `/home/nemo157/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo-miri runner /home/nemo157/.cargo/shared-target/miri/x86_64-unknown-linux-gnu/debug/foo`
foo 1

Nemo157 avatar Sep 12 '22 20:09 Nemo157

Huh... why does this get compiled in $HOME/.cargo at all instead of in the target dir. Do you have something set up to make cargo share its target directories? We may not be able to handle that at present (also: does this work without miri and just regular cargo run?)

oli-obk avatar Sep 13 '22 06:09 oli-obk

Yes, I configure the build.target-dir in my ~/.cargo/config.

cargo run handles it fine as long as the source file is newer than the existing artifact (such as when creating and running the two crates in series like the example).

Nemo157 avatar Sep 13 '22 08:09 Nemo157

We don't do anything ourselves here so the question would be why cargo invokes us on outdated files.

RalfJung avatar Sep 13 '22 14:09 RalfJung

> CARGO_LOG=trace cargo run
...
[2022-09-13T17:39:21Z DEBUG cargo::core::compiler::fingerprint] fingerprint at: /home/nemo157/.cargo/shared-target/debug/.fingerprint/foo-814f88d2d60fb717/bin-foo
[2022-09-13T17:39:21Z DEBUG cargo::core::compiler::fingerprint] max output mtime for "/tmp/tmp.DIIl3W4IFR/foo" is "/home/nemo157/.cargo/shared-target/debug/deps/foo-814f88d2d60fb717" 1663090718.433117604s
[2022-09-13T17:39:21Z INFO  cargo::core::compiler::fingerprint] stale: changed "/tmp/tmp.DIIl3W4IFR/foo/src/main.rs"
[2022-09-13T17:39:21Z INFO  cargo::core::compiler::fingerprint]           (vs) "/home/nemo157/.cargo/shared-target/debug/.fingerprint/foo-814f88d2d60fb717/dep-bin-foo"
[2022-09-13T17:39:21Z INFO  cargo::core::compiler::fingerprint]                FileTime { seconds: 1663090718, nanos: 93111945 } != FileTime { seconds: 1663090759, nanos: 113787222 }
[2022-09-13T17:39:21Z INFO  cargo::core::compiler::fingerprint] fingerprint error for foo v0.1.0 (/tmp/tmp.DIIl3W4IFR/foo)/Build/TargetInner { name: "foo", doc: true, ..: with_path("/tmp/tmp.DIIl3W4IFR/foo/src/main.rs", Edition2021) }
[2022-09-13T17:39:21Z INFO  cargo::core::compiler::fingerprint]     err: current filesystem status shows we're outdated
...
> CARGO_LOG=trace cargo miri run
...
[2022-09-13T17:40:06Z DEBUG cargo::core::compiler::fingerprint] fingerprint at: /home/nemo157/.cargo/shared-target/miri/x86_64-unknown-linux-gnu/debug/.fingerprint/foo-29122c0f4528b228/bin-foo
[2022-09-13T17:40:06Z DEBUG cargo::core::compiler::fingerprint] max output mtime for "/tmp/tmp.DIIl3W4IFR/foo" is "/home/nemo157/.cargo/shared-target/miri/x86_64-unknown-linux-gnu/debug/deps/foo-29122c0f4528b228" 1663015990.683521804s
[2022-09-13T17:40:06Z DEBUG cargo::core::compiler::fingerprint] all paths up-to-date relative to "/home/nemo157/.cargo/shared-target/miri/x86_64-unknown-linux-gnu/debug/.fingerprint/foo-29122c0f4528b228/dep-bin-foo" mtime=1663015990.683521804s
[2022-09-13T17:40:06Z DEBUG cargo::core::compiler::fingerprint] filesystem up-to-date "/tmp/tmp.DIIl3W4IFR/foo"
...

Unfortunately it doesn't say what the most recent file is if it believes the build was up to date.

Nemo157 avatar Sep 13 '22 17:09 Nemo157

I added some more logging into a local cargo, for some reason it doesn't know which source files to check when running under miri:

> CARGO_LOG=trace ~/.cargo/shared-target/debug/cargo run
...
[2022-09-13T17:54:31Z INFO  cargo::core::compiler::fingerprint] checking stale files for "/home/nemo157/.cargo/shared-target/debug/.fingerprint/foo-814f88d2d60fb717/dep-bin-foo" RustcDepInfo { files: ["/tmp/tmp.DIIl3W4IFR/foo/src/main.rs"], env: [] }
...
> CARGO_LOG=trace ~/.cargo/shared-target/debug/cargo miri run
...
[2022-09-13T17:53:13Z INFO  cargo::core::compiler::fingerprint] checking stale files for "/home/nemo157/.cargo/shared-target/miri/x86_64-unknown-linux-gnu/debug/.fingerprint/foo-29122c0f4528b228/dep-bin-foo" RustcDepInfo { files: [], env: [] }
...

What's really weird is that I also see the same logs when I just edit the src/main.rs within a crate, but somehow it results in the updated code running, even though the fingerprint says it is up to date and there is never a Compiling <crate> log line emitted.

Nemo157 avatar Sep 13 '22 18:09 Nemo157

My guess would be that the issue is that around here, we are emitting an empty .d file, which might make cargo think that this "binary" (really a JSON file for Miri) never has to be regenerated.

Emitting a correct depinfo file could be tricky (we'd have to actually invoke rustc); maybe we can get away with some trick such as deleting the fake "binary" after it was executed, thus forcing cargo to re-generate this file each time?

RalfJung avatar Sep 13 '22 19:09 RalfJung

Just adding the json file and the crate root source file to the depinfo file would be enough for this, right?

bjorn3 avatar Sep 13 '22 20:09 bjorn3