Race condition when trying to compile a lib multiple times for different purposes. · Issue #5444 · rust-lang/cargo (original) (raw)

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.

  1. One compilation creates a hardlink.
  2. The other compilation fails to create a hardlink with EEXIST.
  3. 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.