question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Multiple RuntimeHostConfigurationOption for the same switch

See original GitHub issue

Software Versions

I’m using .NET 7 RC1 on macOS ARM64.

Overview

Let’s use the switch System.Threading.Thread.EnableAutoreleasePool for an example.

In the linker’s Microsoft.NET.ILLink.targets file, it sets the property AutoreleasePoolSupport to true if it is not currently set. This will cause the SDK’s Microsoft.NET.Sdk.targets file to create a RuntimeHostConfigurationOption item for System.Threading.Thread.EnableAutoreleasePool. If the user had already created their own System.Threading.Thread.EnableAutoreleasePool item for the System.Threading.Thread.EnableAutoreleasePool switch, they will now have multiple RuntimeHostConfigurationOption entries for the same switch. What finally ends up in the runtime config might not be what they expect.

This problem applies to other properties the linker sets, not just AutoreleasePoolSupport.

Reproduction Program

Use dotnet new console and then edit the csproj file to contain:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PublishTrimmed>true</PublishTrimmed>
  </PropertyGroup>

  <ItemGroup>
    <RuntimeHostConfigurationOption Include="System.Threading.Thread.EnableAutoreleasePool" Value="true" Trim="true" />
  </ItemGroup>

  <Target Name="PrintStuff" AfterTargets="Publish">
    <Message Text="RuntimeHostConfigurationOption: %(RuntimeHostConfigurationOption.Identity)=%(RuntimeHostConfigurationOption.Value)" Importance="High" />
  </Target>

</Project>

Then run:

dotnet publish -r osx-arm64 --self-contained
cat bin/Debug/net7.0/osx-arm64/publish/*.runtimeconfig.json

Expected

The dotnet publish command prints a single entry for System.Threading.Thread.EnableAutoreleasePool and the mytest.runtimeconfig.json has the switch set to true.

Actual

Dotnet publish output

  mytest -> /Users/austin/src/mytest/bin/Debug/net7.0/osx-arm64/publish/
  RuntimeHostConfigurationOption: System.Threading.Thread.EnableAutoreleasePool=true
  RuntimeHostConfigurationOption: Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability=true
  RuntimeHostConfigurationOption: System.ComponentModel.TypeConverter.EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization=false
  RuntimeHostConfigurationOption: System.Resources.ResourceManager.AllowCustomResourceTypes=false
  RuntimeHostConfigurationOption: System.Runtime.InteropServices.BuiltInComInterop.IsSupported=false
  RuntimeHostConfigurationOption: System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting=false
  RuntimeHostConfigurationOption: System.Runtime.InteropServices.EnableCppCLIHostActivation=false
  RuntimeHostConfigurationOption: System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization=false
  RuntimeHostConfigurationOption: System.StartupHookProvider.IsSupported=false
  RuntimeHostConfigurationOption: System.Threading.Thread.EnableAutoreleasePool=false
  RuntimeHostConfigurationOption: System.Text.Encoding.EnableUnsafeUTF7Encoding=false

Note that System.Threading.Thread.EnableAutoreleasePool appears multiple times, once true and once false.

Runtime config file:

{
  "runtimeOptions": {
    "tfm": "net7.0",
    "includedFrameworks": [
      {
        "name": "Microsoft.NETCore.App",
        "version": "7.0.0-rc.1.22426.10"
      }
    ],
    "configProperties": {
      "System.Threading.Thread.EnableAutoreleasePool": false,
      "Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true,
      "System.ComponentModel.TypeConverter.EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization": false,
      "System.Resources.ResourceManager.AllowCustomResourceTypes": false,
      "System.Runtime.InteropServices.BuiltInComInterop.IsSupported": false,
      "System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting": false,
      "System.Runtime.InteropServices.EnableCppCLIHostActivation": false,
      "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false,
      "System.StartupHookProvider.IsSupported": false,
      "System.Text.Encoding.EnableUnsafeUTF7Encoding": false
    }
  }
}

Note that System.Threading.Thread.EnableAutoreleasePool is false, despite what our project file specified.

Workaround

Use the AutoreleasePoolSupport property instead of the RuntimeHostConfigurationOption item.

Possible fixes

Perhaps the Microsoft.NET.ILLink.targets file should also check if the user has set a RuntimeHostConfigurationOption for the switch before setting the AutoreleasePoolSupport property.

Another possibility is the SDK’s targets should check for existing RuntimeHostConfigurationOption item before setting it second time.

Or perhaps something should check for duplicate RuntimeHostConfigurationOption entries for the same switch.

For what it’s worth, NativeAOT’s ILC exits with a failure message when it see the same app context switch multiple times.

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
marcpopMSFTcommented, Nov 9, 2022

@vitek-karas @sbomer moved this to the backlog (so lower priority). Please comment if you feel that we should try to solve this. Seems fairly niche.

0reactions
marcpopMSFTcommented, Nov 9, 2022

Potentially the SDK could throw an error when we detect duplicate values for the runtime config but that would be a “breaking change”. Leave it to do Daniel if he wants to make that change but it doesn’t seem high priority to me. A better solution is to detect that the value is already set and not overwrite the value from what the customer set.

Read more comments on GitHub >

github_iconTop Results From Across the Web

NET Runtime configuration settings
Multiple instances of your application run at the same time on a single system, and you want to configure each for optimum performance....
Read more >
NET 6 System.Drawing.Common Runtime Switch
Next create a file named runtimeconfig.template.json in the same directory as your project file containing: { "configProperties": { "System.
Read more >
Runtime Host Configuration Options and AppContext data ...
In .NET Core, as well as in .NET Framework 4.6+, there is an AppContext type, which was designed as a mechanism to provide...
Read more >
Deep-dive into .NET Core primitives, part 3: runtimeconfig. ...
The purpose of the file is to define required shared frameworks (for framework-dependency deployments only), as well as other runtime options, ...
Read more >
.NET 7 Release Candidate 2 Is Here — Here's What's New!
NET 7 Release Candidate 2 (RC2) was just released by Microsoft, giving us a sneak peek of some of the new additions that...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found