You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Concurrent shared compilations can fail releasing the client mutex on Linux #134043
After Csc and Vbc opted into MSBuild multithreaded task execution in dotnet/roslyn#84701, a dotnet/sdk file-based-app test can intermittently fail when -mt builds two project references in the same MSBuild process with shared compilation enabled:
Microsoft.CSharp.Core.targets(97,5): error MSB3883: Unexpected exception:
Microsoft.CSharp.Core.targets(97,5): error : Cannot release a lock that is not owned by the current thread.
The failure is tracked by dotnet/sdk#56238. It occurred on Ubuntu 22.04 x64 with .NET 11 SDK 11.0.100-ci; test history reported a 0.52% failure rate. The failing Helix log shows LibraryB completing while another compiler invocation fails.
Distinguishing trigger
The failing test creates a file-based app with two #:project references and runs:
dotnet build Program.cs -mt
It also sets MSBUILDUSESERVER=0, so the MSBuild server is disabled while Roslyn shared compilation remains enabled. In the same 108-test work item, the ordinary file-based builds passed; only MultiThreadedArgument_BuildsProjectReferencesInProcess(0, -mt) failed. Its -mt:false row passed immediately afterward.
dotnet/sdk#56239 proposes UseSharedCompilation=false for this one test to isolate its MSBuild in-process-node assertion. That is useful test isolation, but it is a mitigation rather than a fix for this failure.
Relevant implementation and history
BuildServerConnection.RunServerBuildRequestAsync serializes server startup with a named client mutex. Its tryConnectToServerAsync local function is deliberately non-async so WaitOne and ReleaseMutex execute on the same thread. However, Roslyn's current tests exercise requests sequentially and do not appear to cover concurrent calls sharing the same pipe/client mutex from one process.
dotnet/runtime#53420, closed in July after the failure had not been observed following the .NET 11 wait-subsystem transition
dotnet/dotnet#4088, where the same raw exception came from ServerNamedMutex.Dispose
The runtime synchronization correction associated with dotnet/dotnet#4088 is present in the runtime used by this failure, so this appears to be a recurrence exposed by the new concurrent compiler-task execution rather than simply a missing backflow.
The current failure also lacks Roslyn's WaitOne Id / Release Id diagnostic. tryConnectToServerAsync catches ApplicationException around mutex disposal, while the .NET 11 Unix implementation surfaced this ownership failure as InvalidOperationException in dotnet/dotnet#4088.
Requested investigation
Add a Linux regression/stress test that invokes RunServerBuildRequestAsync concurrently with the same pipe name, or otherwise runs concurrent shared-compilation Csc tasks.
Determine whether Roslyn is violating the mutex lifetime contract or whether this is a .NET 11 Unix named-mutex regression; transfer or split the runtime portion if needed.
Preserve the acquisition/release thread IDs when this exception occurs on .NET 11 so a future occurrence is actionable.
Note
This report was prepared with GitHub Copilot assistance from the linked failure logs and source investigation.
Description
After
CscandVbcopted into MSBuild multithreaded task execution in dotnet/roslyn#84701, adotnet/sdkfile-based-app test can intermittently fail when-mtbuilds two project references in the same MSBuild process with shared compilation enabled:The failure is tracked by dotnet/sdk#56238. It occurred on Ubuntu 22.04 x64 with .NET 11 SDK
11.0.100-ci; test history reported a 0.52% failure rate. The failing Helix log showsLibraryBcompleting while another compiler invocation fails.Distinguishing trigger
The failing test creates a file-based app with two
#:projectreferences and runs:It also sets
MSBUILDUSESERVER=0, so the MSBuild server is disabled while Roslyn shared compilation remains enabled. In the same 108-test work item, the ordinary file-based builds passed; onlyMultiThreadedArgument_BuildsProjectReferencesInProcess(0, -mt)failed. Its-mt:falserow passed immediately afterward.dotnet/sdk#56239 proposes
UseSharedCompilation=falsefor this one test to isolate its MSBuild in-process-node assertion. That is useful test isolation, but it is a mitigation rather than a fix for this failure.Relevant implementation and history
BuildServerConnection.RunServerBuildRequestAsyncserializes server startup with a named client mutex. ItstryConnectToServerAsynclocal function is deliberately non-async soWaitOneandReleaseMutexexecute on the same thread. However, Roslyn's current tests exercise requests sequentially and do not appear to cover concurrent calls sharing the same pipe/client mutex from one process.This resembles:
ServerNamedMutex.DisposeThe runtime synchronization correction associated with dotnet/dotnet#4088 is present in the runtime used by this failure, so this appears to be a recurrence exposed by the new concurrent compiler-task execution rather than simply a missing backflow.
The current failure also lacks Roslyn's
WaitOne Id/Release Iddiagnostic.tryConnectToServerAsynccatchesApplicationExceptionaround mutex disposal, while the .NET 11 Unix implementation surfaced this ownership failure asInvalidOperationExceptionin dotnet/dotnet#4088.Requested investigation
RunServerBuildRequestAsyncconcurrently with the same pipe name, or otherwise runs concurrent shared-compilationCsctasks.Note
This report was prepared with GitHub Copilot assistance from the linked failure logs and source investigation.