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

Upgrading to .NET6 breaks unit tests which launch 32-bit .NET processes #22647

Closed
handerss-spotfire opened this issue Nov 17, 2021 · 4 comments
Closed
Assignees

Comments

@handerss-spotfire
Copy link

Tests which launch 32-bit .NET processes fail after upgrading to .NET6 when run from the CLI (running via VS works fine). The 32-bit exe fails to launch with:

The library hostfxr.dll was found, but loading it from C:\Program Files\dotnet\host\fxr\6.0.0\hostfxr.dll failed
   - Installing .NET prerequisites might help resolve this problem.
      https://go.microsoft.com/fwlink/?linkid=798306

The issue does not occur when using .NET5 or when running the test via the VS test explorer.

The issue has been reported on the NUnit3TestAdapter repo since, but apparently the adapter is in play even when running via the VS test explorer (suggesting that the issue may lie elsewhere). Issue: nunit/nunit3-vs-adapter#917

Here's a repo with a minimal reproducible example and a COREHOST trace file: https://github.com/handerss-tibco/net6-nunit-32bit-fail
Here's the trace file: https://github.com/handerss-tibco/net6-nunit-32bit-fail/blob/main/trace.txt
The trace file indicates that the runtime identifier is being set to 64-bit before launch of the 32-bit exe:

Property NATIVE_DLL_SEARCH_DIRECTORIES = C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0\;
Property PLATFORM_RESOURCE_ROOTS = C:\Source\TestProcess32\UnitTest\bin\Debug\net6.0\;
Property APP_CONTEXT_BASE_DIRECTORY = C:\Source\TestProcess32\UnitTest\bin\Debug\net6.0\
Property APP_CONTEXT_DEPS_FILES = C:\Source\TestProcess32\UnitTest\bin\Debug\net6.0\UnitTest.deps.json;C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0\Microsoft.NETCore.App.deps.json
Property PROBING_DIRECTORIES = 
Property RUNTIME_IDENTIFIER = win10-x64
Property System.Reflection.Metadata.MetadataUpdater.IsSupported = false
CoreCLR path = 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0\coreclr.dll', CoreCLR dir = 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0\'
Loaded library from C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0\coreclr.dll
Launch host: C:\Source\TestProcess32\UnitTest\bin\Debug\net6.0\testhost.exe, app: C:\Source\TestProcess32\UnitTest\bin\Debug\net6.0\testhost.dll, argc: 10, args: --port,61918,--endpoint,127.0.0.1:061918,--role,client,--parentprocessid,127200,--telemetryoptedin,false,
--- Begin breadcrumb write
Breadcrumbs will be written using a background thread
Breadcrumb thread write callback...
--- End breadcrumb write 1
Tracing enabled @ Tue Nov 16 14:00:45 2021 GMT
--- Invoked apphost [version: 6.0.0, commit hash: 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6] main = {
TestProcess32.exe
}
Redirecting errors to custom writer.
The managed DLL bound to this executable is: 'TestProcess32.dll'
Using environment variable DOTNET_ROOT=[C:\Program Files\dotnet] as runtime location.
Reading fx resolver directory=[C:\Program Files\dotnet\host\fxr]
Considering fxr version=[2.1.30]...
Considering fxr version=[5.0.12]...
Considering fxr version=[6.0.0]...
Detected latest fxr version=[C:\Program Files\dotnet\host\fxr\6.0.0]...
Resolved fxr [C:\Program Files\dotnet\host\fxr\6.0.0\hostfxr.dll]...
Failed to load the dll from [C:\Program Files\dotnet\host\fxr\6.0.0\hostfxr.dll], HRESULT: 0x800700C1
The library hostfxr.dll was found, but loading it from C:\Program Files\dotnet\host\fxr\6.0.0\hostfxr.dll failed
  - Installing .NET prerequisites might help resolve this problem.
     https://go.microsoft.com/fwlink/?linkid=798306

Versions:
.NET SDK: 6.0.100
Microsoft.NET.Test.Sdk 17.0.0
NUnit 3.13.2
NUnit3TestAdapter: 4.1.0

@handerss-spotfire
Copy link
Author

The issue is only reproducible when the 32-bit process being launched is .NET6 (compiling it for .NET5 resolves the issue).

@vitek-karas vitek-karas removed the untriaged Request triage from a team member label Nov 19, 2021
@MarcoRossignoli
Copy link
Member

MarcoRossignoli commented Nov 19, 2021

We did some change on framework resolver algorithm in 6.0 that breaks this specific scenario; start x86 process from x64 test host process.
New logic for apphost build on 6.0 fallbacks to DOTNET_ROOT environment variable to find the runtime location in addition to the evaluation of DOTNET_ROOT(x86) for x86 architecture process(done in 5.0).
By default testhost process runs with DOTNET_ROOT set to the standard global location path for the current running architecture, so for instance on x64 SDK on Windows the path will be usually C:\Program Files\dotnet.
Now this environment variable is inherited by TestProcess32.exe and so 6.0 apphost loads wrong framework resolver(x64 file format on x86 apphost process).

You can try 2 workaround to solve the issue.

  1. Remove DOTNET_ROOT environment variable before process start
  process.StartInfo.EnvironmentVariables.Remove("DOTNET_ROOT");
  1. Install x86 version of SDK 6.0 and run test with the same architecture of TestProcess32.exe
    Test project csproj
<PropertyGroup>
    <TargetFramework>6.0</TargetFramework>
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>
& "C:\Program Files (x86)\dotnet\dotnet" test 

@handerss-spotfire
Copy link
Author

The first workaround works well, feel free to close.

Is this also the recommended way of running a 32-bit .NET EXE if the host has set DOTNET_ROOT in general?

@MarcoRossignoli
Copy link
Member

Generally speaking, you should not set DOTNET_ROOT* environment variables, test host process is a special case.
You should do it only if you want to specify where to find the host framework resolver(hostfxr) and usually is useful for scenario where you want to run using "private SDK installations".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants