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

Publishing a solution with 6.0 exe and 3.1 classlib to the same target path produces a corrupted output #25226

Open
loop-evgeny opened this issue Apr 28, 2022 · 11 comments
Assignees
Labels
untriaged Request triage from a team member

Comments

@loop-evgeny
Copy link

loop-evgeny commented Apr 28, 2022

Description

I created a .NET 6.0 C# project that referenced a .NET Core 3.1 project, published it as a self-contained application and tried to run it on a Linux server, but it threw the FileLoadException below. It turns out it's not even necessary to reference the .NET 3.1 project - it's enough for it to be included in the solution.

Reproduction Steps

Extract repro.zip and in the repro directory (where repro.sln is) run:

dotnet publish --nologo -c Release --self-contained -r linux-x64 -o bin/pub-linux
cd bin/pub-linux
./repro

(I originally ran it on a remote server, but the problem still reproduces on the same machine where .NET SDK is installed.)

Expected behavior

The application runs and prints "It ran! (DATE/TIME)"

Actual behavior

System.IO.FileLoadException: Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The located assembly's manifest definition does not match the assembly reference. (0x80131040)
File name: 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

Regression?

Don't know.

Known Workarounds

It works when not building a self-contained application (but of course then the runtime has to be installed on the target server).

Configuration

Happens on Ubuntu 18.04.6 and Linux Mint 20 (based on Ubuntu 20.04), both x64.

$ dotnet --info
.NET SDK (reflecting any global.json):
Version: 6.0.202
Commit: f8a5561

Runtime Environment:
OS Name: ubuntu
OS Version: 18.04
OS Platform: Linux
RID: ubuntu.18.04-x64
Base Path: /usr/share/dotnet/sdk/6.0.202/

Host (useful for support):
Version: 6.0.4
Commit: be98e88c76

.NET SDKs installed:
6.0.202 [/usr/share/dotnet/sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.4 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.4 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

Other information

dotnet publish appears to change which runtime DLLs are included depending on whether the .NET Core 3.1 project is referenced or not, so I'm guessing that the 3.1 version of System.Runtime.dll is getting mixed in somehow. Oddly, this only seems to happen when the .NET Core 3.1 project is outside the solution directory (as it is in the attached repro).

@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged Request triage from a team member label Apr 28, 2022
@loop-evgeny
Copy link
Author

The only mentions of that exact error I could find were in dotnet/format#1306 (which has no solution) and dotnet/efcore#27660 where the fix is to add <RollForward>Major</RollForward> to the project properties, but that didn't fix it for me.

@ghost
Copy link

ghost commented Apr 28, 2022

Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

I created a .NET 6.0 C# project that referenced a .NET Core 3.1 project, published it as a self-contained application and tried to run it on a Linux server, but it threw the FileLoadException below. It turns out it's not even necessary to reference the .NET 3.1 project - it's enough for it to be included in the solution.

Reproduction Steps

Extract repro.zip and in the repro directory (where repro.sln is) run:

dotnet publish --nologo -c Release --self-contained -r linux-x64 -o bin/pub-linux
cd bin/pub-linux
./repro

(I originally ran it on a remote server, but the problem still reproduces on the same machine where .NET SDK is installed.)

Expected behavior

The application runs and prints "It ran! (DATE/TIME)"

Actual behavior

System.IO.FileLoadException: Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The located assembly's manifest definition does not match the assembly reference. (0x80131040)
File name: 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

Regression?

Don't know.

Known Workarounds

It works when not building a self-contained application (but of course then the runtime has to be installed on the target server).

Configuration

Happens on Ubuntu 18.04.6 and Linux Mint 20 (based on Ubuntu 20.04), both x64.

$ dotnet --info
.NET SDK (reflecting any global.json):
Version: 6.0.202
Commit: f8a5561

Runtime Environment:
OS Name: ubuntu
OS Version: 18.04
OS Platform: Linux
RID: ubuntu.18.04-x64
Base Path: /usr/share/dotnet/sdk/6.0.202/

Host (useful for support):
Version: 6.0.4
Commit: be98e88c76

.NET SDKs installed:
6.0.202 [/usr/share/dotnet/sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.4 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.4 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

Other information

dotnet publish appears to change which runtime DLLs are included depending on whether the .NET Core 3.1 project is referenced or not, so I'm guessing that the 3.1 version of System.Runtime.dll is getting mixed in somehow. Oddly, this only seems to happen when the .NET Core 3.1 project is outside the solution directory (as it is in the attached repro).

Author: loop-evgeny
Assignees: -
Labels:

area-Host, untriaged

Milestone: -

@vitek-karas
Copy link
Member

I tried on Windows - unfortunately it works just fine for me.

Couple of questions about your repro:

  • There's no reference between the two projects, they're just in the same solution. So as far as I can tell it makes no difference that there's a 3.1 project
  • Can you try creating an empty 6.0 project - just dotnet new console and publish it the same way and run it - to see if it works or fails the same way
  • Can you grab a callstack of the exception? Where is it coming from?

@loop-evgeny
Copy link
Author

Can you grab a callstack of the exception?

Do you know how I can do that?

@vitek-karas
Copy link
Member

I would expect it to get printed out - is that not the case? The text in your original issue - is that the entire output of the app?

If so, you may also want to try runtime tracing: https://docs.microsoft.com/en-us/dotnet/core/dependency-loading/collect-details
Or maybe even host tracing: https://docs.microsoft.com/en-us/dotnet/core/dependency-loading/default-probing#how-do-i-debug-the-probing-properties-construction

One other thing I noticed - you added a framework reference to ASP.NET. A better way to do that is to use:

<Project Sdk="Microsoft.NET.Sdk.Web">

I don't think it should break the app this way, but give it a try.

@loop-evgeny
Copy link
Author

loop-evgeny commented May 5, 2022

There's no reference between the two projects, they're just in the same solution

Correct. I called the folder "referenced" because in my real solution the .NET 6 project referenced the .NET 3.1 project, but then I found that I can repro the problem just by having the .NET 3.1 project in the solution, without a reference.

So as far as I can tell it makes no difference that there's a 3.1 project

I can see dotnet publish at least running a restore for it, so it makes some difference.

Can you try creating an empty 6.0 project - just dotnet new console

By itself that works fine:

em@emvc:/media/sf_work/Bugs/dotnet-68666/repro2/consoleproj$ dotnet publish --nologo -c Release --self-contained -r linux-x64 -o bin/pub-linux
  Determining projects to restore...
  Restored /media/sf_work/Bugs/dotnet-68666/repro2/consoleproj/consoleproj.csproj (in 363 ms).
  consoleproj -> /media/sf_work/Bugs/dotnet-68666/repro2/consoleproj/bin/Release/net6.0/linux-x64/consoleproj.dll
  consoleproj -> /media/sf_work/Bugs/dotnet-68666/repro2/consoleproj/bin/pub-linux/
em@emvc:/media/sf_work/Bugs/dotnet-68666/repro2/consoleproj$ bin/pub-linux/consoleproj
Hello, World!

... but if I add that .NET 3.1 project to the same solution, with the solution file in the consoleproj directory (as per the original repro) I can repro the bug:

em@emvc:/media/sf_work/Bugs/dotnet-68666/repro2/consoleproj$ dotnet publish --nologo -c Release --self-contained -r linux-x64 -o bin/pub-linux
  Determining projects to restore...
  Restored /media/sf_work/Bugs/dotnet-68666/repro2/consoleproj/consoleproj.csproj (in 307 ms).
  Restored /media/sf_work/Bugs/dotnet-68666/repro2/referenced/net31project/net31project.csproj (in 307 ms).
  net31project -> /media/sf_work/Bugs/dotnet-68666/repro2/referenced/net31project/bin/Release/netcoreapp3.1/linux-x64/net31project.dll
  net31project -> /media/sf_work/Bugs/dotnet-68666/repro2/consoleproj/bin/pub-linux/
  consoleproj -> /media/sf_work/Bugs/dotnet-68666/repro2/consoleproj/bin/Release/net6.0/linux-x64/consoleproj.dll
  consoleproj -> /media/sf_work/Bugs/dotnet-68666/repro2/consoleproj/bin/pub-linux/
em@emvc:/media/sf_work/Bugs/dotnet-68666/repro2/consoleproj$ bin/pub-linux/consoleproj
Unhandled exception. System.IO.FileLoadException: Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The located assembly's manifest definition does not match the assembly reference. (0x80131040)
File name: 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
Aborted (core dumped)

So yes, the error in the original issue is the entire output!

I tried COREHOST_TRACE per your link (COREHOST_TRACE=1 bin/pub-linux/consoleproj >corehost-trace.txt 2>&1) and it gives a lot of output, but not a stack trace. Here it is:
corehost-trace.txt

The repro with a console project instead of an ASP.NET one:
repro2.zip

@vitek-karas
Copy link
Member

I tried again on Linux (WSL) and still works for me.
Based on the exception - maybe there's a problem elsewhere. Would it be possible to share the built version of the project - the binaries? Since it's self-contained it should be 100% repro pretty much anywhere... and that will let me look into it in a more detail.

@loop-evgeny
Copy link
Author

Sure, here you go: http://files.loop54.com/Files/Evgeny/consoleproj-pub-linux.zip (can't upload that here, probably too big)

@vitek-karas
Copy link
Member

There's something really weird going on. The files are a combination of .NBT 6 (the app, native bits of the runtime like libcoreclr.so), .NET Core 3.1 (most of the System.* assemblies) and .NET Framework 4.* (some of the System.* assemblies, for example System.Runtime.dll).

It seems that running dotnet publish in a directory which has an .sln file will publish that solution. But if you also specify -o path all of the projects in the solution will be published to the same output directory.
Combine that with the fact that dotnet publish --self-contained on a classlib project (the .NET 3.1 project is a classlib - it doesn't have OutputType=exe) is effectively undefined behavior (I know... I've been complaining about this for a while), it produces a really weird output where some assemblies are 3.1 and some are 4.* - no idea how.

In short if the two projects are published in the wrong order (the console app first, then the 3.1 reference) it will produce basically garbage in the output folder.

If you run dotnet publish consoleproj.csproj then it will only build that one app and everything seems to work correctly.
In my case I didn't get a repro because first I didn't try with -o path (didn't seem important) and later when I did use it, I got lucky and it built the 3.1 first and then the consoleproj which overwrote everything with version 6.

@vitek-karas vitek-karas transferred this issue from dotnet/runtime May 5, 2022
@vitek-karas vitek-karas changed the title Could not load file or assembly 'System.Runtime, Version=6.0.0.0 ... (0x80131040) in self-contained app when solution contains a .NET 3.1 project Publishing a solution with 6.0 exe and 3.1 classlib to the same target path produces a corrupted output May 5, 2022
@vitek-karas
Copy link
Member

@loop-evgeny I moved the issue to the sdk repo (since this is a build-time problem) and updated the title to better match what's going on.

As a workaround - run publish on a project directly, not on the solution (or directory in this case), that should make it work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
untriaged Request triage from a team member
Projects
None yet
Development

No branches or pull requests

4 participants