Skip to content

Don't compile CurrentThreadWorkingDirectory into every binary#13243

Merged
JanProvaznik merged 2 commits intodotnet:mainfrom
DustinCampbell:fix-per-binary-thread-working-directory
Feb 12, 2026
Merged

Don't compile CurrentThreadWorkingDirectory into every binary#13243
JanProvaznik merged 2 commits intodotnet:mainfrom
DustinCampbell:fix-per-binary-thread-working-directory

Conversation

@DustinCampbell
Copy link
Copy Markdown
Member

I spotted this issue while working on different code.

MultiThreadedTaskEnvironmentDriver sets FileUtilities.CurrentThreadWorkingDirectory. However, FileUtilities is linked into every MSBuild binary. That means that any reads of FileUtilities.CurrentThreadWorkingDirectory from other MSBuild binaries will never get the value that MultiThreadedTaskEnvironmentDriver set. Such reads can occur whenever FileUtilities.ItemSpecModifiers.GetItemSpecModifier(...) is called for "FullPath".

The fix I've made is to move the property to FrameworkFileUtilities, which is compiled (once!) into Microsoft.Build.Framework and is accessible everywhere.

MultiThreadedTaskEnvironmentDriver sets FileUtilities.CurrentThreadWorkingDirectory. However, FileUtilities is linked into every MSBuild binary. That means that any reads of that property from other MSBuild binaries won't ever get the value that MultiThreadedTaskEnvironmentDriver set. Such reads can occur whenever FileUtilities.ItemSpecModifiers.GetItemSpecModifier(...) is called for "FullPath".

The fix is to much the property to FrameworkFileUtilities, which is compiled (once!) into Microsoft.Build.Framework and is accessible everywhere.
Copilot AI review requested due to automatic review settings February 12, 2026 01:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR centralizes the per-execution “current working directory” used during property/item expansion so that all MSBuild binaries in-proc observe the same value (fixing incorrect relative path resolution in multithreaded builds when code crosses assembly boundaries).

Changes:

  • Moved CurrentThreadWorkingDirectory from Microsoft.Build.Shared.FileUtilities into Microsoft.Build.Framework.FrameworkFileUtilities (as an AsyncLocal).
  • Updated item-spec modifier expansion (%(FullPath)) and expander path helpers to read FrameworkFileUtilities.CurrentThreadWorkingDirectory.
  • Updated MultiThreadedTaskEnvironmentDriver to set/clear the new centralized location.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/Shared/Modifiers.cs Uses FrameworkFileUtilities.CurrentThreadWorkingDirectory when currentDirectory is null for %(FullPath) expansion.
src/Shared/FileUtilities.cs Removes the duplicated per-binary CurrentThreadWorkingDirectory static from shared FileUtilities.
src/Framework/FileUtilities.cs Adds AsyncLocal-backed CurrentThreadWorkingDirectory to FrameworkFileUtilities (non-TASKHOST).
src/Build/Evaluation/Expander/WellKnownFunctions.cs Updates Path.GetFullPath well-known function behavior to use the centralized working directory.
src/Build/Evaluation/Expander.cs Updates expansion helpers to use FrameworkFileUtilities.CurrentThreadWorkingDirectory as the thread/async-local base directory.
src/Build/BackEnd/TaskExecutionHost/MultiThreadedTaskEnvironmentDriver.cs Sets/clears the centralized working directory when ProjectDirectory changes / driver disposes.

Comment thread src/Shared/Modifiers.cs Outdated
Comment thread src/Shared/Modifiers.cs Outdated
Copy link
Copy Markdown
Member

@JanProvaznik JanProvaznik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for catching this!

@JanProvaznik JanProvaznik merged commit 178ecc9 into dotnet:main Feb 12, 2026
10 checks passed
@DustinCampbell DustinCampbell deleted the fix-per-binary-thread-working-directory branch February 12, 2026 16:47
@jaredpar
Copy link
Copy Markdown
Member

Nice find!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants