Skip to content

Race condition creating symlinks on Windows results in a junction to empty directory being created instead of a symlink to a file #19018

@carpenterjc

Description

@carpenterjc

Description of the bug:

While using a cc_import to add a dependency to a cc_binary that is produced by a custom starlark rule elsewhere in the repository.

This executable is then use by and run by a cc_test.

What we find is rarely bazel will create "symlink" the file before it is written by the custom rule. When this happens bazel will create a directory junction instead of a symlink to the file.

Sometimes what is supposed to be a symlink (or copy, if symlinks are disabled) shows up as a directory junction instead (this breaks -- you cannot interact with a directory junction which points at a file)
When you're in this state, bazel build doesn't fix the problem. Only a bazel clean or manually removing the junction fixes it.
It appears to be a race condition, because it doesn't happen consistently.
Code inspection of the bazel symlink implementation for Windows shows that it creates a directory junction either if the target exists and is a directory, or if the target doesn't exist -- even if symlinks are disabled on Windows.
This implies the bug: if the core.symlink action is scheduled ahead of the action which generates the link target, it will always produce the wrong result on Windows.

What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

This happens rarely and we believe its a race condition.

Which operating system are you running Bazel on?

Windows 11

What is the output of bazel info release?

release 6.2.0

If bazel info release returns development version or (@non-git), tell us how you built Bazel.

No response

What's the output of git remote get-url origin; git rev-parse master; git rev-parse HEAD ?

No response

Is this a regression? If yes, please try to identify the Bazel commit where the bug was introduced.

No response

Have you found anything relevant by searching the web?

https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/windows/WindowsFileSystem.java#L80-L106

that says:
If the target doesn't exist, or if it is a directory, create a junction. We don't check the symlink flag for this case.
Else (the target exists and is a file)
If the symlink flag is enabled, create a symlink
Otherwise copy it (non-atomically, by the way)

Any other information, logs, or outputs that you want to share?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3We're not considering working on this, but happy to review a PR. (No assignee)area-WindowsWindows-specific issues and feature requeststeam-Rules-CPPIssues for C++ rulestype: bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions