Description
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:
Lines 242 to 247 in 46cdac0
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