dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
18.98k stars 4.03k forks source link

Runtime hang after updating net48 project to .NET 8 SDK #72210

Open mthjones opened 8 months ago

mthjones commented 8 months ago

Describe the bug

After attempting to update our net48-targeting application's builds from .NET SDK 7.0.404 to 8.0.101, we ran into previously valid application code consistently hanging in Release builds.

To Reproduce

MRE Github Repo: https://github.com/mthjones/net8sdk-hang-mre/tree/main

The change in behaviour is found in Case 3, and can be triggered with dotnet run -c Release -- 3, when changing the SDK version in global.json between 7.0.404 and 8.0.101.

The IL diff produced by the application on 7.0.404 and 8.0.101:

diff --git "a/C:\\Users\\mjones\\AppData\\Local\\Temp\\tmpC0BE.tmp" "b/C:\\Users\\mjones\\AppData\\Local\\Temp\\tmpC11D.tmp"
index da52341..b3a9ecd 100644
--- "a/C:\\Users\\mjones\\AppData\\Local\\Temp\\tmpC0BE.tmp"
+++ "b/C:\\Users\\mjones\\AppData\\Local\\Temp\\tmpC11D.tmp"
@@ -28,7 +28,10 @@
                                                                                                 6D 72 65 00 00 )                                  // mre..
   .custom instance void [mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = ( 01 00 07 52 65 6C 65 61 73 65 00 00 )             // ...Release..
   .custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( 01 00 07 31 2E 30 2E 30 2E 30 00 00 )             // ...1.0.0.0..
-  .custom instance void [mscorlib]System.Reflection.AssemblyInformationalVersionAttribute::.ctor(string) = ( 01 00 05 31 2E 30 2E 30 00 00 )                   // ...1.0.0..
+  .custom instance void [mscorlib]System.Reflection.AssemblyInformationalVersionAttribute::.ctor(string) = ( 01 00 2E 31 2E 30 2E 30 2B 34 64 62 63 62 31 30   // ...1.0.0+4dbcb10
+                                                                                                             36 36 64 66 36 31 34 34 62 30 63 35 37 34 63 38   // 66df6144b0c574c8
+                                                                                                             31 34 36 36 63 65 66 62 31 62 62 32 62 64 66 63   // 1466cefb1bb2bdfc
+                                                                                                             64 00 00 )                                        // d..
   .custom instance void [mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) = ( 01 00 10 6E 65 74 38 73 64 6B 2D 68 61 6E 67 2D   // ...net8sdk-hang-
                                                                                                 6D 72 65 00 00 )                                  // mre..
   .custom instance void [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = ( 01 00 10 6E 65 74 38 73 64 6B 2D 68 61 6E 67 2D   // ...net8sdk-hang-
@@ -37,13 +40,13 @@
   .ver 1:0:0:0
 }
 .module 'net8sdk-hang-mre.exe'
-// MVID: {C4619B5E-BB80-47A9-8657-D99AE29EE9AC}
+// MVID: {40427478-C9F6-4E7B-9A13-01E75142BE01}
 .imagebase 0x00400000
 .file alignment 0x00000200
 .stackreserve 0x00100000
 .subsystem 0x0003       // WINDOWS_CUI
 .corflags 0x00000001    //  ILONLY
-// Image base: 0x06FD0000
+// Image base: 0x05200000

 // =============== CLASS MEMBERS DECLARATION ===================
@@ -151,7 +154,7 @@

 } // end of class net8sdk_hang_mre.Program

-.class interface public abstract auto ansi net8sdk_hang_mre.IFoo`1<T>
+.class interface public abstract auto ansi beforefieldinit net8sdk_hang_mre.IFoo`1<T>
 {
   .method public hidebysig newslot abstract virtual 
           instance bool  DoSomething() cil managed
@@ -160,11 +163,11 @@

 } // end of class net8sdk_hang_mre.IFoo`1

-.class interface public abstract auto ansi net8sdk_hang_mre.IBaseParams
+.class interface public abstract auto ansi beforefieldinit net8sdk_hang_mre.IBaseParams
 {
 } // end of class net8sdk_hang_mre.IBaseParams

-.class interface public abstract auto ansi net8sdk_hang_mre.IParams
+.class interface public abstract auto ansi beforefieldinit net8sdk_hang_mre.IParams
        implements net8sdk_hang_mre.IBaseParams
 {
 } // end of class net8sdk_hang_mre.IParams

Exceptions (if any)

None.

Further technical details

`dotnet --info` output ``` .NET SDK: Version: 8.0.101 Commit: 6eceda187b Workload version: 8.0.100-manifests.69afb982 Runtime Environment: OS Name: Windows OS Version: 10.0.19044 OS Platform: Windows RID: win-x64 Base Path: C:\Program Files\dotnet\sdk\8.0.101\ .NET workloads installed: Workload version: 8.0.100-manifests.69afb982 There are no installed workloads to display. Host: Version: 8.0.1 Architecture: x64 Commit: bf5e279d92 .NET SDKs installed: 5.0.301 [C:\Program Files\dotnet\sdk] 6.0.301 [C:\Program Files\dotnet\sdk] 6.0.400 [C:\Program Files\dotnet\sdk] 7.0.404 [C:\Program Files\dotnet\sdk] 8.0.100 [C:\Program Files\dotnet\sdk] 8.0.101 [C:\Program Files\dotnet\sdk] .NET runtimes installed: Microsoft.AspNetCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 7.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 7.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Other architectures found: arm64 [C:\Program Files\dotnet] registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\arm64\InstallLocation] x86 [C:\Program Files (x86)\dotnet] registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation] Environment variables: Not set global.json file: C:\Users\mjones\code\net8-beforefieldinit\global.json Learn more: https://aka.ms/dotnet/info Download .NET: https://aka.ms/dotnet/download ```
Matthew-nop commented 8 months ago

Looking a bit deeper into this - it seems like this results from the changes in https://github.com/dotnet/roslyn/pull/69850.

I built the MRE using SDK version 8.0.101 with dotnet build -c Release net8sdk-hang-mre\net8sdk-hang-mre.csproj and then dumped the IL from the executable with ildasm. I've created a gist with this .il file alongside a patch that removes the beforefieldinit flag from interfaces.

When reassembling the IL with ilasm, case 3 hangs indefinitely with the unpatched executable but runs without issue when patched and reassembled.

https://gist.github.com/Matthew-nop/85d4c11c6f66bbc5f2e1088f443e7939

baronfel commented 8 months ago

Cc @jaredpar - should this move to Roslyn for further triage?

aduric commented 6 months ago

Would it be possible to get an update? This is currently blocking net48-targetted applications from being updated to .NET8 SDK. Thank you!