Description
As part of #5384 I created some circumstances where the same lib may be built concurrently with different settings. I thought this would be safe since they have different hashes in the filename, but I neglected to address this case when the library is hardlinked. There is a race condition in hardlink_or_copy
where one compilation will stomp on another via the hardlink.
Details for the curious.
- One compilation creates a hardlink.
- The other compilation fails to create a hardlink with EEXIST.
- 2nd compilation copies its lib into the existing hardlink, modifying the first one's contents.
This can happen in a variety of situations (mainly with panic
), but here is a small repro:
cargo new --lib stomp
cd stomp
cat >> Cargo.toml <<EOL
[profile.dev]
panic = "abort"
EOL
cat > src/main.rs <<EOL
extern crate stomp;
fn main() {}
EOL
# This will fail some of the time on some platforms with wrong panic strategy.
# Note: This requires #5384. Earlier versions would fail 100% of the time.
# This attempts to build `lib.rs` twice at the same time, once with `panic`
# and once without (for tests).
cargo build --all-targets -v
I'm trying to think of a fix, but I haven't come up with anything, yet. Generally I'm thinking that these "non-panic" dependencies should not be hard linked at all, but there's no obvious way to detect when a Unit
is one of these. We could add a flag to Unit
to detect this scenario, but that would require adding some extra de-duplication logic and generally seems a little too complex.
I don't think it is worth it to try to fix the race condition itself since that is very tricky, and would end up with a random lib in the output directory anyway.
I'll keep trying to think of a solution, but if anyone has any thoughts I'd be happy to hear.