Skip to content

LoggerException occurs when trying to use the same binary logger for evaluation and build #11867

@RikkiGibson

Description

@RikkiGibson

Context: The VS Code C# extension throws an exception when loading projects with setting "dotnet.projects.binaryLogPath" specified.

VS Code error log
2025-05-19 10:33:59.335 [info] [Error - 10:33:59 AM] [workspace/didChangeWatchedFiles] [LanguageServerProjectLoader] Error while loading c:\Users\rigibson\src\ConsoleApp5\Program.cs: Exception thrown: Microsoft.CodeAnalysis.MSBuild.RemoteInvocationException: An exception of type Microsoft.Build.Framework.LoggerException was thrown: Failed to write to log file "C:\Users\rigibson\AppData\Local\Programs\Microsoft VS Code\binlogs\LanguageServerDesignTimeBuild-df194f26-35a6-49fa-9bc4-a895752f774e-1.binlog". The process cannot access the file 'C:\Users\rigibson\AppData\Local\Programs\Microsoft VS Code\binlogs\LanguageServerDesignTimeBuild-df194f26-35a6-49fa-9bc4-a895752f774e-1.binlog' because it is being used by another process.
   at Microsoft.CodeAnalysis.MSBuild.RpcClient.InvokeCoreAsync(Int32 targetObject, String methodName, List`1 parameters, Type expectedReturnType, CancellationToken cancellationToken) in /_/src/Workspaces/MSBuild/Core/Rpc/RpcClient.cs:line 186
   at Microsoft.CodeAnalysis.MSBuild.RpcClient.InvokeAsync[T](Int32 targetObject, String methodName, List`1 parameters, CancellationToken cancellationToken) in /_/src/Workspaces/MSBuild/Core/Rpc/RpcClient.cs:line 135
   at Microsoft.CodeAnalysis.MSBuild.RemoteBuildHost.LoadProjectAsync(String projectFilePath, String projectContent, String languageName, CancellationToken cancellationToken) in /_/src/Workspaces/MSBuild/Core/Rpc/RemoteBuildHost.cs:line 41
   at Microsoft.CodeAnalysis.LanguageServer.HostWorkspace.FileBasedProgramsProjectSystem.TryLoadProjectInMSBuildHostAsync(BuildHostProcessManager buildHostProcessManager, String documentPath, CancellationToken cancellationToken) in /_/src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/FileBasedProgramsProjectSystem.cs:line 141
   at Microsoft.CodeAnalysis.LanguageServer.HostWorkspace.LanguageServerProjectLoader.ReloadProjectAsync(ProjectToLoad projectToLoad, ToastErrorReporter toastErrorReporter, BuildHostProcessManager buildHostProcessManager, CancellationToken cancellationToken) in /_/src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/LanguageServerProjectLoader.cs:line 208
2025-05-19 10:33:59.340 [info] [Info  - 10:33:59 AM] [workspace/didChangeWatchedFiles] [LanguageServerProjectLoader] Completed (re)load of all projects in 00:00:01.1469839
2025-05-19 10:33:59.341 [info] [Debug - 10:33:59 AM] [workspace/didChangeWatchedFiles] [BuildHost PID 10208] Sending a Shutdown request to the BuildHost.
2025-05-19 10:33:59.343 [info] [Error - 10:33:59 AM] [workspace/didChangeWatchedFiles] [BuildHost PID 10208] Exception while shutting down the BuildHost process. Microsoft.CodeAnalysis.MSBuild.RemoteInvocationException: An exception of type System.InvalidOperationException was thrown: Operation is not valid due to the current state of the object.
   at Microsoft.CodeAnalysis.MSBuild.RpcClient.InvokeCoreAsync(Int32 targetObject, String methodName, List`1 parameters, Type expectedReturnType, CancellationToken cancellationToken) in /_/src/Workspaces/MSBuild/Core/Rpc/RpcClient.cs:line 186
   at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.BuildHostProcess.DisposeAsync() in /_/src/Workspaces/MSBuild/Core/MSBuild/BuildHostProcessManager.cs:line 434
2025-05-19 10:33:59.343 [info] [Error - 10:33:59 AM] [workspace/didChangeWatchedFiles] 

What is happening is: BinaryLogger.Initialize is being called twice. Each time a write stream to the binlog file is opened. The second time, an IOException occurs because the first time locked the file.

Both calls to BinaryLogger.Initialize occur indirectly thru a single call to ProjectBuildManager.StartBatchBuild in Roslyn.

First call (thru ProjectBuildManager.cs#L231)
Microsoft.Build.dll!Microsoft.Build.Logging.BinaryLogger.Initialize(Microsoft.Build.Framework.IEventSource eventSource) Line 79	C#
Microsoft.Build.dll!Microsoft.Build.Evaluation.ProjectCollection.ReusableLogger.Initialize(Microsoft.Build.Framework.IEventSource eventSource, int nodeCount) Line 221	C#
Microsoft.Build.dll!Microsoft.Build.BackEnd.Logging.LoggingService.InitializeLogger(Microsoft.Build.Framework.ILogger logger, Microsoft.Build.Framework.IEventSource sourceForLogger) Line 982	C#
Microsoft.Build.dll!Microsoft.Build.BackEnd.Logging.LoggingService.RegisterDistributedLogger(Microsoft.Build.Framework.ILogger centralLogger, Microsoft.Build.Logging.LoggerDescription forwardingLogger) Line 578	C#
Microsoft.Build.dll!Microsoft.Build.BackEnd.Logging.LoggingService.RegisterLogger(Microsoft.Build.Framework.ILogger logger) Line 537	C#
Microsoft.Build.dll!Microsoft.Build.Evaluation.ProjectCollection.RegisterLoggerInternal(Microsoft.Build.Framework.ILogger logger) Line 1660	C#
Microsoft.Build.dll!Microsoft.Build.Evaluation.ProjectCollection.RegisterLoggers(System.Collections.Generic.IEnumerable<Microsoft.Build.Framework.ILogger> loggers) Line 1405	C#
Microsoft.Build.dll!Microsoft.Build.Evaluation.ProjectCollection.ProjectCollection(System.Collections.Generic.IDictionary<string, string> globalProperties, System.Collections.Generic.IEnumerable<Microsoft.Build.Framework.ILogger> loggers, System.Collections.Generic.IEnumerable<Microsoft.Build.Logging.ForwardingLoggerRecord> remoteLoggers, Microsoft.Build.Evaluation.ToolsetDefinitionLocations toolsetDefinitionLocations, int maxNodeCount, bool onlyLogCriticalEvents, bool loadProjectsReadOnly, bool useAsynchronousLogging, bool reuseProjectRootElementCache) Line 1127	C#
Microsoft.Build.dll!Microsoft.Build.Evaluation.ProjectCollection.ProjectCollection(System.Collections.Generic.IDictionary<string, string> globalProperties, System.Collections.Generic.IEnumerable<Microsoft.Build.Framework.ILogger> loggers, System.Collections.Generic.IEnumerable<Microsoft.Build.Logging.ForwardingLoggerRecord> remoteLoggers, Microsoft.Build.Evaluation.ToolsetDefinitionLocations toolsetDefinitionLocations, int maxNodeCount, bool onlyLogCriticalEvents, bool loadProjectsReadOnly) Line 1097	C#
Microsoft.Build.dll!Microsoft.Build.Evaluation.ProjectCollection.ProjectCollection(System.Collections.Generic.IDictionary<string, string> globalProperties, System.Collections.Generic.IEnumerable<Microsoft.Build.Framework.ILogger> loggers, System.Collections.Generic.IEnumerable<Microsoft.Build.Logging.ForwardingLoggerRecord> remoteLoggers, Microsoft.Build.Evaluation.ToolsetDefinitionLocations toolsetDefinitionLocations, int maxNodeCount, bool onlyLogCriticalEvents) Line 1092	C#
Microsoft.Build.dll!Microsoft.Build.Evaluation.ProjectCollection.ProjectCollection(System.Collections.Generic.IDictionary<string, string> globalProperties, System.Collections.Generic.IEnumerable<Microsoft.Build.Framework.ILogger> loggers, Microsoft.Build.Evaluation.ToolsetDefinitionLocations toolsetDefinitionLocations) Line 1080	C#
Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll!Microsoft.CodeAnalysis.MSBuild.ProjectBuildManager.StartBatchBuild(System.Collections.Generic.IDictionary<string, string> globalProperties) Line 231	C#
Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll!Microsoft.CodeAnalysis.MSBuild.BuildHost.CreateBuildManager() Line 122	C#
Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll!Microsoft.CodeAnalysis.MSBuild.BuildHost.LoadProjectCore(string projectFilePath, string projectContent, string languageName) Line 205	C#
Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll!Microsoft.CodeAnalysis.MSBuild.BuildHost.LoadProject(string projectFilePath, string projectContent, string languageName) Line 176	C#
Second call (thru ProjectBuildManager.cs#L243)
Microsoft.Build.dll!Microsoft.Build.Logging.BinaryLogger.Initialize(Microsoft.Build.Framework.IEventSource eventSource) Line 79	C#
Microsoft.Build.dll!Microsoft.Build.BackEnd.Logging.LoggingService.InitializeLogger(Microsoft.Build.Framework.ILogger logger, Microsoft.Build.Framework.IEventSource sourceForLogger) Line 986	C#
Microsoft.Build.dll!Microsoft.Build.BackEnd.Logging.LoggingService.RegisterDistributedLogger(Microsoft.Build.Framework.ILogger centralLogger, Microsoft.Build.Logging.LoggerDescription forwardingLogger) Line 578	C#
Microsoft.Build.dll!Microsoft.Build.BackEnd.Logging.LoggingService.RegisterLogger(Microsoft.Build.Framework.ILogger logger) Line 537	C#
Microsoft.Build.dll!Microsoft.Build.Execution.BuildManager.CreateLoggingService(System.Collections.Generic.IEnumerable<Microsoft.Build.Framework.ILogger> loggers, System.Collections.Generic.IEnumerable<Microsoft.Build.Logging.ForwardingLoggerRecord> forwardingLoggers, System.Collections.Generic.ISet<string> warningsAsErrors, System.Collections.Generic.ISet<string> warningsNotAsErrors, System.Collections.Generic.ISet<string> warningsAsMessages) Line 2000	C#
Microsoft.Build.dll!Microsoft.Build.Execution.BuildManager.BeginBuild.__InitializeLoggingService|64_0() Line 443	C#
Microsoft.Build.dll!Microsoft.Build.Execution.BuildManager.BeginBuild(Microsoft.Build.Execution.BuildParameters parameters) Line 360	C#
Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll!Microsoft.CodeAnalysis.MSBuild.ProjectBuildManager.StartBatchBuild(System.Collections.Generic.IDictionary<string, string> globalProperties) Line 243	C#
Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll!Microsoft.CodeAnalysis.MSBuild.BuildHost.CreateBuildManager() Line 122	C#
Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll!Microsoft.CodeAnalysis.MSBuild.BuildHost.LoadProjectCore(string projectFilePath, string projectContent, string languageName) Line 205	C#
Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll!Microsoft.CodeAnalysis.MSBuild.BuildHost.LoadProject(string projectFilePath, string projectContent, string languageName) Line 176	C#

From discussion with @dibarbet we believe this is a regression. In the past, the usage pattern shown in the linked code did not result in multiple initialization of the BinaryLogger. We were thus able to log both the evaluation and build of a project to the same binlog file at design time.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions