rust-lang / miri

An interpreter for Rust's mid-level intermediate representation
Apache License 2.0
4.14k stars 318 forks source link

"local crate" detection does not work any more #3643

Closed narpfel closed 1 month ago

narpfel commented 1 month ago

When splitting a package into multiple crates, backtraces only show underlined code for frames in the binary crate but not for the library crate or workspace members:

Example `src/main.rs`: ```rust fn main() { t::entry_point(); } ``` `src/lib.rs`: ```rust pub fn entry_point() { a(); } fn a() { b(); } fn b() { c(); } fn c() { unsafe { std::hint::unreachable_unchecked(); } } ``` Backtrace: ```console $ cargo miri run error: Undefined Behavior: entering unreachable code --> /tmp/t/src/lib.rs:15:9 | 15 | std::hint::unreachable_unchecked(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ entering unreachable code | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `t::c` at /tmp/t/src/lib.rs:15:9: 15:43 = note: inside `t::b` at /tmp/t/src/lib.rs:10:5: 10:8 = note: inside `t::a` at /tmp/t/src/lib.rs:6:5: 6:8 = note: inside `t::entry_point` at /tmp/t/src/lib.rs:2:5: 2:8 note: inside `main` --> src/main.rs:2:5 | 2 | t::entry_point(); | ^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace error: aborting due to 1 previous error ```
Workspace example Workspace members `a` (binary crate) and `b` (library crate): `a/src/main.rs`: ```rust fn main() { dbg!(env!("MIRI_LOCAL_CRATES")); f() } fn f() { g() } fn g() { h() } fn h() { b::entry_point() } ``` `b/src/lib.rs`: ```rust pub fn entry_point() { a() } fn a() { b() } fn b() { c() } fn c() { unsafe { std::hint::unreachable_unchecked() } } ``` Backtrace: ```console $ cargo miri run [a/src/main.rs:2:5] env!("MIRI_LOCAL_CRATES") = "path+file:///tmp/q/a#0.1.0,path+file:///tmp/q/b#0.1.0" error: Undefined Behavior: entering unreachable code --> /tmp/q/b/src/lib.rs:15:9 | 15 | std::hint::unreachable_unchecked() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ entering unreachable code | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `b::c` at /tmp/q/b/src/lib.rs:15:9: 15:43 = note: inside `b::b` at /tmp/q/b/src/lib.rs:10:5: 10:8 = note: inside `b::a` at /tmp/q/b/src/lib.rs:6:5: 6:8 = note: inside `b::entry_point` at /tmp/q/b/src/lib.rs:2:5: 2:8 note: inside `h` --> a/src/main.rs:15:5 | 15 | b::entry_point() | ^^^^^^^^^^^^^^^^ note: inside `g` --> a/src/main.rs:11:5 | 11 | h() | ^^^ note: inside `f` --> a/src/main.rs:7:5 | 7 | g() | ^^^ note: inside `main` --> a/src/main.rs:3:5 | 3 | f() | ^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace error: aborting due to 1 previous error ```

The relevant code fragments in entry_point, a, and b are not shown in the backtrace, even though they’re in a local crate (MIRI_LOCAL_CRATES contains the crate b). Only note: inside [...] is printed.

AFAIU, this is the same issue that was solved in #2024, so I tested the examples with nightly-2022-04-01 (a few weeks after #2024 was merged), and all code fragments are properly shown. Also, the contents of MIRI_LOCAL_CRATES are different:

`cargo +nightly-2022-04-01 miri run` ```console $ cargo +nightly-2022-04-01 miri run [a/src/main.rs:2] env!("MIRI_LOCAL_CRATES") = "a,b" error: Undefined Behavior: entering unreachable code --> /rustup/toolchains/nightly-2022-04-01-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/hint.rs:51:14 | 51 | unsafe { intrinsics::unreachable() } | ^^^^^^^^^^^^^^^^^^^^^^^^^ entering unreachable code | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: inside `std::hint::unreachable_unchecked` at /rustup/toolchains/nightly-2022-04-01-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/hint.rs:51:14 note: inside `b::c` at /tmp/q/b/src/lib.rs:15:9 --> /tmp/q/b/src/lib.rs:15:9 | 15 | std::hint::unreachable_unchecked() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: inside `b::b` at /tmp/q/b/src/lib.rs:10:5 --> /tmp/q/b/src/lib.rs:10:5 | 10 | c() | ^^^ note: inside `b::a` at /tmp/q/b/src/lib.rs:6:5 --> /tmp/q/b/src/lib.rs:6:5 | 6 | b() | ^^^ note: inside `b::entry_point` at /tmp/q/b/src/lib.rs:2:5 --> /tmp/q/b/src/lib.rs:2:5 | 2 | a() | ^^^ note: inside `h` at a/src/main.rs:15:5 --> a/src/main.rs:15:5 | 15 | b::entry_point() | ^^^^^^^^^^^^^^^^ note: inside `g` at a/src/main.rs:11:5 --> a/src/main.rs:11:5 | 11 | h() | ^^^ note: inside `f` at a/src/main.rs:7:5 --> a/src/main.rs:7:5 | 7 | g() | ^^^ note: inside `main` at a/src/main.rs:3:5 --> a/src/main.rs:3:5 | 3 | f() | ^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace error: aborting due to previous error ```

Apparently, the format of cargo metadata was changed:

$ cargo +nightly-2022-04-01 metadata | jq .workspace_members
[
  "a 0.1.0 (path+file:///tmp/q/a)",
  "b 0.1.0 (path+file:///tmp/q/b)"
]
$ cargo metadata | jq .workspace_members
[
  "path+file:///tmp/q/a#0.1.0",
  "path+file:///tmp/q/b#0.1.0"
]

cargo PR that changed .workspace_members: https://github.com/rust-lang/cargo/pull/12914 Issue about this change: https://github.com/rust-lang/cargo/issues/13528

The fix seems to be to use the strings from .workspace_members to look up the package name in .packages by their id here: https://github.com/rust-lang/miri/blob/46cdac08c62da34e5b607873be8cf0ae5f58341f/cargo-miri/src/util.rs#L242-L247


Rust version:

$ rustc --version --verbose
rustc 1.80.0-nightly (84b40fc90 2024-05-27)
binary: rustc
commit-hash: 84b40fc908c3adc7e0e470b3fbaa264df0e122b8
commit-date: 2024-05-27
host: x86_64-unknown-linux-gnu
release: 1.80.0-nightly
LLVM version: 18.1.6