Skip to content

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

Closed
@narpfel

Description

@narpfel

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:

fn main() {
    t::entry_point();
}

src/lib.rs:

pub fn entry_point() {
    a();
}

fn a() {
    b();
}

fn b() {
    c();
}

fn c() {
    unsafe {
        std::hint::unreachable_unchecked();
    }
}

Backtrace:

$ 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:

fn main() {
    dbg!(env!("MIRI_LOCAL_CRATES"));
    f()
}

fn f() {
    g()
}

fn g() {
    h()
}

fn h() {
    b::entry_point()
}

b/src/lib.rs:

pub fn entry_point() {
    a()
}

fn a() {
    b()
}

fn b() {
    c()
}

fn c() {
    unsafe {
        std::hint::unreachable_unchecked()
    }
}

Backtrace:

$ 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`
$ 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: rust-lang/cargo#12914
Issue about this change: rust-lang/cargo#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:

miri/cargo-miri/src/util.rs

Lines 242 to 247 in 46cdac0

for member in &metadata.workspace_members {
let name = member.repr.split(' ').next().unwrap();
let name = name.replace('-', "_");
local_crates.push_str(&name);
local_crates.push(',');
}


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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-cargoArea: affects the cargo wrapper (cargo miri)C-bugCategory: This is a bug.E-good-first-issueA good way to start contributing, mentoring is available

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions