Multiple RuntimeHostConfigurationOption for the same switch
See original GitHub issueSoftware 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:
- Created a year ago
- Comments:7 (7 by maintainers)
Top GitHub Comments
@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.
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.