Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenProjectAsync() is failing in docker container with base image of mcr.microsoft.com/dotnet/sdk:6.0 #71784

Open
sivaji55 opened this issue Jan 24, 2024 · 5 comments · May be fixed by #76832 or #72257
Open
Assignees
Labels
Milestone

Comments

@sivaji55
Copy link

sivaji55 commented Jan 24, 2024

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CodeAnalysis.CSharp.Syntax;

var workspace = MSBuildWorkspace.Create();
Project project = default!;
try
{
    project = workspace.OpenProjectAsync("/ApiLibrary/Test.API/Test.API.csproj").Result;
}
catch(Exception ex)
{
    Console.WriteLine(ex);
    return;
}
var compilation = await project.GetCompilationAsync();
var result = compilation.Emit("output.dll");

above code works fine in windows, but same code is not working in docker container with base image of mcr.microsoft.com/dotnet/sdk:6.0

Expected Behavior:
It should open the project and compile it

Actual Behavior:

System.AggregateException: One or more errors occurred. (Broken pipe)
 ---> System.IO.IOException: Broken pipe
 ---> System.Net.Sockets.SocketException (32): Broken pipe
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.CreateException(SocketError error, Boolean forAsyncThrow)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.SendAsync(Socket socket, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.SendAsync(ReadOnlyMemory`1 buffer, SocketFlags socketFlags, CancellationToken cancellationToken)
   at System.IO.Pipes.PipeStream.WriteAsyncCore(ReadOnlyMemory`1 source, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at System.IO.Pipes.PipeStream.WriteAsyncCore(ReadOnlyMemory`1 source, CancellationToken cancellationToken)
   at System.IO.Pipes.PipeStream.WriteAsync(ReadOnlyMemory`1 buffer, CancellationToken cancellationToken)
   at System.IO.StreamWriter.<FlushAsyncInternal>g__Core|76_0(Boolean flushStream, Boolean flushEncoder, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at System.IO.StreamWriter.<FlushAsyncInternal>g__Core|76_0(Boolean flushStream, Boolean flushEncoder, CancellationToken cancellationToken)
   at System.IO.StreamWriter.FlushAsyncInternal(Boolean flushStream, Boolean flushEncoder, CancellationToken cancellationToken)
   at System.IO.StreamWriter.FlushAsync()
   at Microsoft.CodeAnalysis.MSBuild.Rpc.RpcClient.InvokeCoreAsync(Int32 targetObject, String methodName, List`1 parameters, Type expectedReturnType, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.CodeAnalysis.MSBuild.Rpc.RpcClient.InvokeCoreAsync(Int32 targetObject, String methodName, List`1 parameters, Type expectedReturnType, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.Rpc.RpcClient.InvokeAsync[T](Int32 targetObject, String methodName, List`1 parameters, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.CodeAnalysis.MSBuild.Rpc.RpcClient.InvokeAsync[T](Int32 targetObject, String methodName, List`1 parameters, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.Rpc.RemoteBuildHost.LoadProjectFileAsync(String projectFilePath, String languageName, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.CodeAnalysis.MSBuild.Rpc.RemoteBuildHost.LoadProjectFileAsync(String projectFilePath, String languageName, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.<>c__DisplayClass20_0.<LoadProjectFileInfosAsync>b__1()   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.DoOperationAndReportProgressAsync[TResult](ProjectLoadOperation operation, String projectPath, String targetFramework, Func`1 doFunc)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectFileInfosAsync(String projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectFileInfosAsync(String projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectInfosFromPathAsync(String projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectInfosFromPathAsync(String projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadAsync(CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadAsync(CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadProjectInfoAsync(String projectFilePath, ProjectMap projectMap, IProgress`1 progress, ILogger msbuildLogger, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadProjectInfoAsync(String projectFilePath, ProjectMap projectMap, IProgress`1 progress, ILogger msbuildLogger, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenProjectAsync(String projectFilePath, ILogger msbuildLogger, IProgress`1 progress, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenProjectAsync(String projectFilePath, ILogger msbuildLogger, IProgress`1 progress, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenProjectAsync(String projectFilePath, IProgress`1 progress, CancellationToken cancellationToken)
   at Program.<Main>$(String[] args) in /App/Program.cs:line 10
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Program.<Main>$(String[] args)
   at Program.<Main>(String[] args)
--- End of stack trace from previous location ---
   at System.IO.Pipes.PipeStream.WriteAsyncCore(ReadOnlyMemory`1 source, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.IO.Pipes.PipeStream.WriteAsyncCore(ReadOnlyMemory`1 source, CancellationToken cancellationToken)
   at System.IO.StreamWriter.<FlushAsyncInternal>g__Core|76_0(Boolean flushStream, Boolean flushEncoder, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.Rpc.RpcClient.InvokeCoreAsync(Int32 targetObject, String methodName, List`1 parameters, Type expectedReturnType, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.Rpc.RpcClient.InvokeAsync[T](Int32 targetObject, String methodName, List`1 parameters, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.Rpc.RemoteBuildHost.LoadProjectFileAsync(String projectFilePath, String languageName, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.DoOperationAndReportProgressAsync[TResult](ProjectLoadOperation operation, String projectPath, String targetFramework, Func`1 doFunc)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectFileInfosAsync(String projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectInfosFromPathAsync(String projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadAsync(CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadProjectInfoAsync(String projectFilePath, ProjectMap projectMap, IProgress`1 progress, ILogger msbuildLogger, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadProjectInfoAsync(String projectFilePath, ProjectMap projectMap, IProgress`1 progress, ILogger msbuildLogger, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenProjectAsync(String projectFilePath, ILogger msbuildLogger, IProgress`1 progress, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at Program.<Main>$(String[] args) in /App/Program.cs:line 10
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Jan 24, 2024
@vladimirKa002
Copy link

Hi. I experienced same error after switching to 4.9.0-3.final version due to this issue. After downgrading it to 4.8.0, it started working in Docker. Make sure to have this list of package refs:

<PackageReference Include="Microsoft.Build" Version="17.8.3" />
<PackageReference Include="Microsoft.Build.Framework" Version="17.8.3" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="17.8.3" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.8.3" />
<PackageReference Include="Microsoft.Build.Locator" Version="1.6.10" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />

<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.8.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.8.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.8.0" />

It seems like with current pre-release version it is improssible to run analysis in Docker.

What configuration in your project file and Dockerfile do you have?

@sivaji55
Copy link
Author

It is working now, after I downgrade packages from 4.9.0-3.final to 4.6.0

my project file:

<PropertyGroup>
	<OutputType>Exe</OutputType>
	<TargetFramework>net6.0</TargetFramework>
	<ImplicitUsings>enable</ImplicitUsings>
	<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
	<PackageReference Include="Microsoft.Build.Locator" Version="1.6.10" />
	<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.6.0" />
	<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.6.0" />
	<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.6.0" />
</ItemGroup>

I can reproduce the same issue in windows as well, latest packages working in my local windows machine as I have .net 8 sdk, and same code is failing in docker container with .net 6 sdk, when I downgrade packages to 4.6.0 now same code is working fine in docker container as well.

@jasonmalinowski jasonmalinowski self-assigned this Jan 31, 2024
@jasonmalinowski jasonmalinowski added IDE-MSBuildWorkspace MSBuildWorkspace and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Jan 31, 2024
@jasonmalinowski
Copy link
Member

Reactivating since this is a regression in the 4.9.0 packages.

@jasonmalinowski
Copy link
Member

Created #71909 to give a bit better diagnosability here.

@jasonmalinowski
Copy link
Member

So I'm realizing we have a bigger problem here: we may have generally dropped support for net6.0 when we moved our build to net8.0. That's not intentional, but will mean that later 4.9 packages are not going to even compile with net6.0.

jasonmalinowski added a commit to jasonmalinowski/roslyn that referenced this issue Feb 24, 2024
Before this change we were building the Workspaces.MSBuild library (the
part that loads in the end user's application process) as a .NET Core
and .NET Framework library with no netstandard target, which meant that
if we weren't careful we'd move our .NET Core TFM to something newer
than what customers still expect us to support. All of our other
libraries target netstandard but this one was still special. This was
because some MSBuild NuGet packages themselves don't target netstandard
and so we wre forced to do the same.

Digging further we realized that Microsoft.Build.Framwork, which defines
ILogger was already netstandard compatible, and so our only remaining
use of an not-netstandard package was Microsoft.Build, which only
existed to read solution files. That I fixed in our prior commit, so
at this point the only NuGet packages we still referenced were
.NET Standard compatible. Great!

There wa one more surprise though: the BuildHost we ship as content
files in subdirectories, but we were also shipping the DLL as a regular
referenced library in the end user's application. This was to provide
the serialization exchange types to the RPC client, as well as share
some useful helpers that were needed on both sides. But since the
BuildHost still cannot target netstandard because it does need MSBuild
libraries that are not yet netstandard, it meant that the regular
Workspaces.MSBuild.dll project couldn't reference the BuildHost DLL
anymore either. So to break that link I move the handful of files we
were needing on both sides to a shared project, and then just include
that shared project into both the build host and library/client
projects. This means we can break the ProjectReference link entirely.

At some point MSBuild will make their other package netstandard, which
means that split wasn't strictly necessary to do, but honestly it
resulted in some downstream hacks so I believe it's a net win
regardless. There was extra MSBuild/NuGet magic to make sure the
binary was included in the other project without it appearing as a
package reference. The only way to do that was to set PrivateAssets=all,
which then meant other projects had to remember to reference that
lest we fail to deploy a DLL. It was very much a fight against tooling,
and severing the project references just cleans things up nicely.

Fixes dotnet#71784
jasonmalinowski added a commit to jasonmalinowski/roslyn that referenced this issue Feb 24, 2024
Before this change we were building the Workspaces.MSBuild library (the
part that loads in the end user's application process) as a .NET Core
and .NET Framework library with no netstandard target, which meant that
if we weren't careful we'd move our .NET Core TFM to something newer
than what customers still expect us to support. All of our other
libraries target netstandard but this one was still special. This was
because some MSBuild NuGet packages themselves don't target netstandard
and so we wre forced to do the same.

Digging further we realized that Microsoft.Build.Framwork, which defines
ILogger was already netstandard compatible, and so our only remaining
use of an not-netstandard package was Microsoft.Build, which only
existed to read solution files. That I fixed in our prior commit, so
at this point the only NuGet packages we still referenced were
.NET Standard compatible. Great!

There wa one more surprise though: the BuildHost we ship as content
files in subdirectories, but we were also shipping the DLL as a regular
referenced library in the end user's application. This was to provide
the serialization exchange types to the RPC client, as well as share
some useful helpers that were needed on both sides. But since the
BuildHost still cannot target netstandard because it does need MSBuild
libraries that are not yet netstandard, it meant that the regular
Workspaces.MSBuild.dll project couldn't reference the BuildHost DLL
anymore either. So to break that link I move the handful of files we
were needing on both sides to a shared project, and then just include
that shared project into both the build host and library/client
projects. This means we can break the ProjectReference link entirely.

At some point MSBuild will make their other package netstandard, which
means that split wasn't strictly necessary to do, but honestly it
resulted in some downstream hacks so I believe it's a net win
regardless. There was extra MSBuild/NuGet magic to make sure the
binary was included in the other project without it appearing as a
package reference. The only way to do that was to set PrivateAssets=all,
which then meant other projects had to remember to reference that
lest we fail to deploy a DLL. It was very much a fight against tooling,
and severing the project references just cleans things up nicely.

Fixes dotnet#71784
jasonmalinowski added a commit to jasonmalinowski/roslyn that referenced this issue Mar 1, 2024
Before this change we were building the Workspaces.MSBuild library (the
part that loads in the end user's application process) as a .NET Core
and .NET Framework library with no netstandard target, which meant that
if we weren't careful we'd move our .NET Core TFM to something newer
than what customers still expect us to support. All of our other
libraries target netstandard but this one was still special. This was
because some MSBuild NuGet packages themselves don't target netstandard
and so we wre forced to do the same.

Digging further we realized that Microsoft.Build.Framwork, which defines
ILogger was already netstandard compatible, and so our only remaining
use of an not-netstandard package was Microsoft.Build, which only
existed to read solution files. That I fixed in our prior commit, so
at this point the only NuGet packages we still referenced were
.NET Standard compatible. Great!

There wa one more surprise though: the BuildHost we ship as content
files in subdirectories, but we were also shipping the DLL as a regular
referenced library in the end user's application. This was to provide
the serialization exchange types to the RPC client, as well as share
some useful helpers that were needed on both sides. But since the
BuildHost still cannot target netstandard because it does need MSBuild
libraries that are not yet netstandard, it meant that the regular
Workspaces.MSBuild.dll project couldn't reference the BuildHost DLL
anymore either. So to break that link I move the handful of files we
were needing on both sides to a shared project, and then just include
that shared project into both the build host and library/client
projects. This means we can break the ProjectReference link entirely.

At some point MSBuild will make their other package netstandard, which
means that split wasn't strictly necessary to do, but honestly it
resulted in some downstream hacks so I believe it's a net win
regardless. There was extra MSBuild/NuGet magic to make sure the
binary was included in the other project without it appearing as a
package reference. The only way to do that was to set PrivateAssets=all,
which then meant other projects had to remember to reference that
lest we fail to deploy a DLL. It was very much a fight against tooling,
and severing the project references just cleans things up nicely.

Fixes dotnet#71784
jasonmalinowski added a commit to jasonmalinowski/roslyn that referenced this issue Mar 4, 2024
Before this change we were building the Workspaces.MSBuild library (the
part that loads in the end user's application process) as a .NET Core
and .NET Framework library with no netstandard target, which meant that
if we weren't careful we'd move our .NET Core TFM to something newer
than what customers still expect us to support. All of our other
libraries target netstandard but this one was still special. This was
because some MSBuild NuGet packages themselves don't target netstandard
and so we wre forced to do the same.

Digging further we realized that Microsoft.Build.Framwork, which defines
ILogger was already netstandard compatible, and so our only remaining
use of an not-netstandard package was Microsoft.Build, which only
existed to read solution files. That I fixed in our prior commit, so
at this point the only NuGet packages we still referenced were
.NET Standard compatible. Great!

There wa one more surprise though: the BuildHost we ship as content
files in subdirectories, but we were also shipping the DLL as a regular
referenced library in the end user's application. This was to provide
the serialization exchange types to the RPC client, as well as share
some useful helpers that were needed on both sides. But since the
BuildHost still cannot target netstandard because it does need MSBuild
libraries that are not yet netstandard, it meant that the regular
Workspaces.MSBuild.dll project couldn't reference the BuildHost DLL
anymore either. So to break that link I move the handful of files we
were needing on both sides to a shared project, and then just include
that shared project into both the build host and library/client
projects. This means we can break the ProjectReference link entirely.

At some point MSBuild will make their other package netstandard, which
means that split wasn't strictly necessary to do, but honestly it
resulted in some downstream hacks so I believe it's a net win
regardless. There was extra MSBuild/NuGet magic to make sure the
binary was included in the other project without it appearing as a
package reference. The only way to do that was to set PrivateAssets=all,
which then meant other projects had to remember to reference that
lest we fail to deploy a DLL. It was very much a fight against tooling,
and severing the project references just cleans things up nicely.

Fixes dotnet#71784
@arunchndr arunchndr added this to the Backlog milestone Nov 26, 2024
JoeRobich pushed a commit that referenced this issue Jan 21, 2025
Before this change we were building the Workspaces.MSBuild library (the
part that loads in the end user's application process) as a .NET Core
and .NET Framework library with no netstandard target, which meant that
if we weren't careful we'd move our .NET Core TFM to something newer
than what customers still expect us to support. All of our other
libraries target netstandard but this one was still special. This was
because some MSBuild NuGet packages themselves don't target netstandard
and so we wre forced to do the same.

Digging further we realized that Microsoft.Build.Framwork, which defines
ILogger was already netstandard compatible, and so our only remaining
use of an not-netstandard package was Microsoft.Build, which only
existed to read solution files. That I fixed in our prior commit, so
at this point the only NuGet packages we still referenced were
.NET Standard compatible. Great!

There wa one more surprise though: the BuildHost we ship as content
files in subdirectories, but we were also shipping the DLL as a regular
referenced library in the end user's application. This was to provide
the serialization exchange types to the RPC client, as well as share
some useful helpers that were needed on both sides. But since the
BuildHost still cannot target netstandard because it does need MSBuild
libraries that are not yet netstandard, it meant that the regular
Workspaces.MSBuild.dll project couldn't reference the BuildHost DLL
anymore either. So to break that link I move the handful of files we
were needing on both sides to a shared project, and then just include
that shared project into both the build host and library/client
projects. This means we can break the ProjectReference link entirely.

At some point MSBuild will make their other package netstandard, which
means that split wasn't strictly necessary to do, but honestly it
resulted in some downstream hacks so I believe it's a net win
regardless. There was extra MSBuild/NuGet magic to make sure the
binary was included in the other project without it appearing as a
package reference. The only way to do that was to set PrivateAssets=all,
which then meant other projects had to remember to reference that
lest we fail to deploy a DLL. It was very much a fight against tooling,
and severing the project references just cleans things up nicely.

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