[Bug]: BuildManager fails to dispose of cache plugin after exception thrown during BeginBuild
- Dominant language
- C#
- Stars
- 5.5k
- Forks
- 1.5k
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 141
Description
### Issue Description
BuildManager fails to dispose of the plugin after the exception described in #10615, leading to all future build attempts that use the plugin to fail because the semaphore hasn't been released.
### Steps to Reproduce
See #10615 for repro.
### Expected Behavior
*Subsequent* builds fail with this message appearing only *once*:
> Another instance of MSBuildCache is already running in this build. This is typically due to a misconfiguration of the plugin settings, in particular different plugin settings across projects.
### Actual Behavior
*Subsequent* builds fail with an error message appearing *twice*:
> Another instance of MSBuildCache is already running in this build. This is typically due to a misconfiguration of the plugin settings, in particular different plugin settings across projects.
> Another instance of MSBuildCache is already running in this build. This is typically due to a misconfiguration of the plugin settings, in particular different plugin settings across projects.
### Analysis
The cache plugin is created on this callstack:
```
> Microsoft.MSBuildCache.Local.dll!Microsoft.MSBuildCache.MSBuildCachePluginBase.TryAcquireLock(Microsoft.MSBuildCache.PluginSettings settings, Microsoft.Build.Experimental.ProjectCache.PluginLoggerBase logger) Line 853 C#
Microsoft.MSBuildCache.Local.dll!Microsoft.MSBuildCache.MSBuildCachePluginBase.BeginBuildInnerAsync(Microsoft.Build.Experimental.ProjectCache.CacheContext context, Microsoft.Build.Experimental.ProjectCache.PluginLoggerBase logger, System.Threading.CancellationToken cancellationToken) Line 229 C#
Microsoft.MSBuildCache.Local.dll!Microsoft.MSBuildCache.MSBuildCachePluginBase.TimeAndLogAsync.AnonymousMethod__0() Line 1143 C#
Microsoft.MSBuildCache.Local.dll!Microsoft.MSBuildCache.MSBuildCachePluginBase.TimeAndLogAsync(Microsoft.Build.Experimental.ProjectCache.PluginLoggerBase logger, System.Func> innerAsync, string context, string memberName) Line 1111 C#
Microsoft.MSBuildCache.Local.dll!Microsoft.MSBuildCache.MSBuildCachePluginBase.BeginBuildAsync(Microsoft.Build.Experimental.ProjectCache.CacheContext context, Microsoft.Build.Experimental.ProjectCache.PluginLoggerBase logger, System.Threading.CancellationToken cancellationToken) Line 215 C#
Microsoft.Build.dll!Microsoft.Build.Experimental.ProjectCache.ProjectCacheService.CreateAndInitializePluginAsync(Microsoft.Build.Experimental.ProjectCache.ProjectCacheDescriptor projectCacheDescriptor, Microsoft.Build.Graph.ProjectGraph projectGraph, Microsoft.Build.BackEnd.BuildRequestConfiguration buildRequestConfiguration, System.Collections.Generic.ICollection requestedTargets, System.Threading.CancellationToken cancellationToken) Line 258 C#
Microsoft.Build.dll!Microsoft.Build.Experimental.ProjectCache.ProjectCacheService.GetProjectCachePluginAsync.AnonymousMethod__1() Line 168 C#
mscorlib.dll!System.Lazy>.CreateValue() Unknown
mscorlib.dll!System.Lazy>.LazyInitValue() Unknown
Microsoft.Build.dll!Microsoft.Build.Experimental.ProjectCache.ProjectCacheService.GetProjectCachePluginAsync(Microsoft.Build.Experimental.ProjectCache.ProjectCacheDescriptor projectCacheDescriptor, Microsoft.Build.Graph.ProjectGraph projectGraph, Microsoft.Build.BackEnd.BuildRequestConfiguration buildRequestConfiguration, System.Collections.Generic.ICollection requestedTargets, System.Threading.CancellationToken cancellationToken) Line 164 C#
Microsoft.Build.dll!Microsoft.Build.Experimental.ProjectCache.ProjectCacheService.InitializePluginsForVsScenario.AnonymousMethod__1(Microsoft.Build.Experimental.ProjectCache.ProjectCacheDescriptor projectCacheDescriptor) Line 151 C#
mscorlib.dll!System.Threading.Tasks.Parallel.ForWorker.AnonymousMethod__1() Unknown
mscorlib.dll!System.Threading.Tasks.Task.InnerInvokeWithArg(System.Threading.Tasks.Task childTask) Unknown
mscorlib.dll!System.Threading.Tasks.Task.ExecuteSelfReplicating.AnonymousMethod__0(object ) Unknown
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot) Unknown
mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution) Unknown
mscorlib.dll!System.Threading.Tasks.ThreadPoolTaskScheduler.TryExecuteTaskInline(System.Threading.Tasks.Task task, bool taskWasPreviouslyQueued) Unknown
mscorlib.dll!System.Threading.Tasks.TaskScheduler.TryRunInline(System.Threading.Tasks.Task task, bool taskWasPreviouslyQueued) Unknown
mscorlib.dll!System.Threading.Tasks.Task.InternalRunSynchronously(System.Threading.Tasks.TaskScheduler scheduler, bool waitForCompletion) Unknown
mscorlib.dll!System.Threading.Tasks.Parallel.ForWorker(int fromInclusive, int toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action body, System.Action bodyWithState, System.Func bodyWithLocal, System.Func localInit, System.Action localFinally) Unknown
mscorlib.dll!System.Threading.Tasks.Parallel.ForEachWorker(System.Collections.Generic.IEnumerable source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action body, System.Action bodyWithState, System.Action bodyWithStateAndIndex, System.Func bodyWithStateAndLocal, System.Func bodyWithEverything, System.Func localInit, System.Action localFinally) Unknown
mscorlib.dll!System.Threading.Tasks.Parallel.ForEach(System.Collections.Generic.IEnumerable source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action body) Unknown
Microsoft.Build.dll!Microsoft.Build.Experimental.ProjectCache.ProjectCacheService.InitializePluginsForVsScenario.AnonymousMethod__0() Line 145 C#
mscorlib.dll!System.Threading.Tasks.Task.Execute() Unknown
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot) Unknown
mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution) Unknown
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Unknown
```
I suspect an exception thrown from this isn't caught properly such that the failed plugin will still be disposed of.
### Versions & Configurations
Dev17.12 (35228.240.main)
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.