Skip to content

Race condition when trying to compile a lib multiple times for different purposes. #5444

Closed

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.
  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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions