Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remap libstd paths in backtraces for test crates #85463

Open
jonas-schievink opened this issue May 19, 2021 · 16 comments · May be fixed by #118149
Open

remap libstd paths in backtraces for test crates #85463

jonas-schievink opened this issue May 19, 2021 · 16 comments · May be fixed by #118149
Labels
A-reproducibility Area: Reproducible / Deterministic builds C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@jonas-schievink
Copy link
Contributor

I just got this backtrace when running RUST_BACKTRACE=1 cargo test on salsa-rs/salsa@bb4b42a:

thread 'frozen::in_par_get_set_cancelation' panicked at 'called `Result::unwrap()` on an `Err` value: Any { .. }', tests/parallel/frozen.rs:64:33
stack backtrace:
   0: rust_begin_unwind
             at /rustc/881c1ac408d93bb7adaa3a51dabab9266e82eee8/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/881c1ac408d93bb7adaa3a51dabab9266e82eee8/library/core/src/panicking.rs:92:14
   2: core::result::unwrap_failed
             at /rustc/881c1ac408d93bb7adaa3a51dabab9266e82eee8/library/core/src/result.rs:1355:5
   3: core::result::Result<T,E>::unwrap
             at /home/jonas/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:1037:23
   4: parallel::frozen::in_par_get_set_cancelation
             at ./tests/parallel/frozen.rs:64:18
   5: parallel::frozen::in_par_get_set_cancelation::{{closure}}
             at ./tests/parallel/frozen.rs:13:1
   6: core::ops::function::FnOnce::call_once
             at /home/jonas/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5
   7: core::ops::function::FnOnce::call_once
             at /rustc/881c1ac408d93bb7adaa3a51dabab9266e82eee8/library/core/src/ops/function.rs:227:5

The remapping from /rustc/... paths to the rust-src component only seems to kick in once here, but I expected it to always work (since the component is installed). Frames 6 and 7 also point to the exact same location, but path remapping still failed for one of them.

@jonas-schievink jonas-schievink added the C-bug Category: This is a bug. label May 19, 2021
@jyn514
Copy link
Member

jyn514 commented May 19, 2021

@jonas-schievink what version of rustc is this?

@jonas-schievink
Copy link
Contributor Author

This is on rustc 1.54.0-nightly (881c1ac40 2021-05-08)

@jyn514
Copy link
Member

jyn514 commented May 19, 2021

Can you try with latest nightly? #83813 was merged recently and may have fixed this.

@jonas-schievink
Copy link
Contributor Author

The most recent nightly seems to work even less:

thread 'frozen::in_par_get_set_cancelation' panicked at 'called `Result::unwrap()` on an `Err` value: Any { .. }', tests/parallel/frozen.rs:64:33
stack backtrace:
   0: rust_begin_unwind
             at /rustc/4e3e6db011c5b482d2bef8ba02274657f93b5e0d/library/std/src/panicking.rs:515:5
   1: core::panicking::panic_fmt
             at /rustc/4e3e6db011c5b482d2bef8ba02274657f93b5e0d/library/core/src/panicking.rs:92:14
   2: core::result::unwrap_failed
             at /rustc/4e3e6db011c5b482d2bef8ba02274657f93b5e0d/library/core/src/result.rs:1355:5
   3: core::result::Result<T,E>::unwrap
             at /rustc/4e3e6db011c5b482d2bef8ba02274657f93b5e0d/library/core/src/result.rs:1037:23
   4: parallel::frozen::in_par_get_set_cancelation
             at ./tests/parallel/frozen.rs:64:18
   5: parallel::frozen::in_par_get_set_cancelation::{{closure}}
             at ./tests/parallel/frozen.rs:13:1
   6: core::ops::function::FnOnce::call_once
             at /rustc/4e3e6db011c5b482d2bef8ba02274657f93b5e0d/library/core/src/ops/function.rs:227:5
   7: core::ops::function::FnOnce::call_once
             at /rustc/4e3e6db011c5b482d2bef8ba02274657f93b5e0d/library/core/src/ops/function.rs:227:5

@jyn514
Copy link
Member

jyn514 commented May 19, 2021

@jonas-schievink what do you mean? Those look correctly remapped to /rustc/hash to me, were you expecting something else?

@jyn514
Copy link
Member

jyn514 commented May 19, 2021

Oh I see, you want it to not remap and use the local path.

@jyn514 jyn514 changed the title Path remapping in backtraces is broken Don't remap libstd paths in backtraces for test crates May 19, 2021
@jyn514 jyn514 added C-enhancement Category: An issue proposing an enhancement or a PR with one. and removed C-bug Category: This is a bug. labels May 19, 2021
@jyn514
Copy link
Member

jyn514 commented May 19, 2021

Note that people have requested the opposite behavior in the past, but it seems reasonable to do this only for tests: #82188

@jyn514 jyn514 added the A-reproducibility Area: Reproducible / Deterministic builds label May 19, 2021
@jonas-schievink
Copy link
Contributor Author

jonas-schievink commented May 19, 2021

The /rustc/<hash> path is the non-remapped path. I have the rust-src component installed, so they should be remapped to point there. (my mistake, the terminology used here wasn't clear to me)

@jyn514
Copy link
Member

jyn514 commented May 19, 2021

cc @cbeuw

@jyn514 jyn514 changed the title Don't remap libstd paths in backtraces for test crates remap libstd paths in backtraces for test crates May 19, 2021
@cbeuw
Copy link
Contributor

cbeuw commented May 19, 2021

I see there are some terminology confusions. /rustc/<hash> are technically remapped as it was remapped from some real path during compiler bootstrapping. At compile time it's correlated back to rust-src path if it exists. I would call /rustc/<hash> "virtualised" path and the actual .../.rustup/toolchains/... path "real" or "local" path.

I'm not confident in saying this but I think this can be resolved within std::backtrace? We have a CFG_VIRTUAL_RUST_SOURCE_BASE_DIR containing the local path to the sources, and the backtrace code should be able to use it to map things back? This avoids emitting local paths into the binary which was what we tried to avoid.

@jyn514
Copy link
Member

jyn514 commented May 19, 2021

CFG_VIRTUAL_RUST_SOURCE_BASE_DIR

I haven't looked into the code, but that sounds like it's a compile time constant, so it has the path when rustc is compiled, not when rustc is running. So if you use that it will be unhelpful, it will show things like /home/bors/builds.

@cbeuw
Copy link
Contributor

cbeuw commented May 19, 2021

nvm CFG_VIRTUAL_RUST_SOURCE_BASE_DIR actually contains what the path is virtualised to (i.e. /rustc/<hash>), so it's not too useful here. (It may be used to identify if the path on hand is actually for the Rust source rather than a real path on local system coincidentally starting with /rustc/[a-z0-9]{40}/library/... but that'd be highly unlikely unless the user is deliberately trying to trip things up. In any case we could hardcode CFG_VIRTUAL_RUST_SOURCE_BASE_DIR into rustc during bootstrapping).

The bit that finds the local path to rust source is here

let real_rust_source_base_dir = {
// This is the location used by the `rust-src` `rustup` component.
let mut candidate = sysroot.join("lib/rustlib/src/rust");
if let Ok(metadata) = candidate.symlink_metadata() {
// Replace the symlink rustbuild creates, with its destination.
// We could try to use `fs::canonicalize` instead, but that might
// produce unnecessarily verbose path.
if metadata.file_type().is_symlink() {
if let Ok(symlink_dest) = std::fs::read_link(&candidate) {
candidate = symlink_dest;
}
}
}
// Only use this directory if it has a file we can expect to always find.
if candidate.join("library/std/src/lib.rs").is_file() { Some(candidate) } else { None }
};

The only environment-dependent thing we need here is sysroot on the local file system. Obviously we can't emit that into the binary so maybe we could ask Cargo to supply it?

@jyn514
Copy link
Member

jyn514 commented May 19, 2021

@cbeuw that has the same issue, cargo runs at compiletime, not runtime. There's no way for this to be done at runtime without it being part of the binary, which is why I suggested doing it only for test binaries.

@jyn514
Copy link
Member

jyn514 commented May 19, 2021

I guess as an alternative libtest could read a SYSROOT environment variable set by cargo, but that seems kind of hacky.

@cbeuw
Copy link
Contributor

cbeuw commented May 19, 2021

@jyn514 I'm in the middle of writing an RFC for Cargo that adds a profile setting called trim-path, which is basically an implementation of #40552 (sanitising every potential absolute paths, like paths to Cargo registry) and is enabled by default for release builds.

Prehaps we could make the emission of virtual vs real sysroot paths also dependant on that? It seems a logical thing to do if trim-path gets added. This way both test and debug builds will have real paths embedded by default, and can be overriden manually if the user wishes.

@cbeuw
Copy link
Contributor

cbeuw commented May 25, 2021

RFC's here: rust-lang/rfcs#3127

@cbeuw cbeuw linked a pull request Nov 21, 2023 that will close this issue
bors added a commit to rust-lang-ci/rust that referenced this issue Dec 13, 2023
Implement RFC 3127 sysroot path handling changes

Fix rust-lang#105907
Fix rust-lang#85463

Implement parts of rust-lang#111540

Right now, backtraces into sysroot always shows /rustc/$hash in diagnostics, e.g.

```
thread 'main' panicked at 'hello world', map-panic.rs:2:50
stack backtrace:
   0: std::panicking::begin_panic
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/std/src/panicking.rs:616:12
   1: map_panic::main::{{closure}}
             at ./map-panic.rs:2:50
   2: core::option::Option<T>::map
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/option.rs:929:29
   3: map_panic::main
             at ./map-panic.rs:2:30
   4: core::ops::function::FnOnce::call_once
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```

[RFC 3127 said](https://rust-lang.github.io/rfcs/3127-trim-paths.html#changing-handling-of-sysroot-path-in-rustc)

> We want to change this behaviour such that, when rust-src source files can be discovered, the virtual path is discarded and therefore the local path will be embedded, unless there is a --remap-path-prefix that causes this local path to be remapped in the usual way.

This PR implements this behaviour. When `rust-src` is present at compile time, rustc replaces /rustc/$hash with a real path into local rust-src with best effort. To sanitise this, users must explicitly supply `--remap-path-prefix=<path to rust-src>=foo`.
bors added a commit to rust-lang-ci/rust that referenced this issue Dec 16, 2023
Implement RFC 3127 sysroot path handling changes

Fix rust-lang#105907
Fix rust-lang#85463

Implement parts of rust-lang#111540

Right now, backtraces into sysroot always shows /rustc/$hash in diagnostics, e.g.

```
thread 'main' panicked at 'hello world', map-panic.rs:2:50
stack backtrace:
   0: std::panicking::begin_panic
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/std/src/panicking.rs:616:12
   1: map_panic::main::{{closure}}
             at ./map-panic.rs:2:50
   2: core::option::Option<T>::map
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/option.rs:929:29
   3: map_panic::main
             at ./map-panic.rs:2:30
   4: core::ops::function::FnOnce::call_once
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```

[RFC 3127 said](https://rust-lang.github.io/rfcs/3127-trim-paths.html#changing-handling-of-sysroot-path-in-rustc)

> We want to change this behaviour such that, when rust-src source files can be discovered, the virtual path is discarded and therefore the local path will be embedded, unless there is a --remap-path-prefix that causes this local path to be remapped in the usual way.

This PR implements this behaviour. When `rust-src` is present at compile time, rustc replaces /rustc/$hash with a real path into local rust-src with best effort. To sanitise this, users must explicitly supply `--remap-path-prefix=<path to rust-src>=foo`.
bors added a commit to rust-lang-ci/rust that referenced this issue Dec 16, 2023
Implement RFC 3127 sysroot path handling changes

Fix rust-lang#105907
Fix rust-lang#85463

Implement parts of rust-lang#111540

Right now, backtraces into sysroot always shows /rustc/$hash in diagnostics, e.g.

```
thread 'main' panicked at 'hello world', map-panic.rs:2:50
stack backtrace:
   0: std::panicking::begin_panic
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/std/src/panicking.rs:616:12
   1: map_panic::main::{{closure}}
             at ./map-panic.rs:2:50
   2: core::option::Option<T>::map
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/option.rs:929:29
   3: map_panic::main
             at ./map-panic.rs:2:30
   4: core::ops::function::FnOnce::call_once
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```

[RFC 3127 said](https://rust-lang.github.io/rfcs/3127-trim-paths.html#changing-handling-of-sysroot-path-in-rustc)

> We want to change this behaviour such that, when rust-src source files can be discovered, the virtual path is discarded and therefore the local path will be embedded, unless there is a --remap-path-prefix that causes this local path to be remapped in the usual way.

This PR implements this behaviour. When `rust-src` is present at compile time, rustc replaces /rustc/$hash with a real path into local rust-src with best effort. To sanitise this, users must explicitly supply `--remap-path-prefix=<path to rust-src>=foo`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-reproducibility Area: Reproducible / Deterministic builds C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants