diff --git a/src/coreclr/utilcode/clrconfig.cpp b/src/coreclr/utilcode/clrconfig.cpp
index 59d32c0c43091d..ca6e095504313b 100644
--- a/src/coreclr/utilcode/clrconfig.cpp
+++ b/src/coreclr/utilcode/clrconfig.cpp
@@ -410,7 +410,7 @@ namespace
//
// Arguments:
// * info - see file:../inc/CLRConfig.h for details.
-//
+// * isDefault - the value was not set or had an invalid format so the default was returned.
// * result - the result.
//
// Return value:
@@ -431,9 +431,7 @@ DWORD CLRConfig::GetConfigValue(const ConfigDWORDInfo & info, /* [Out] */ bool *
DWORD resultMaybe;
HRESULT hr = GetConfigDWORD(info.name, info.defaultValue, &resultMaybe, info.options);
-
- // Ignore the default value even if it's set explicitly.
- if (resultMaybe != info.defaultValue)
+ if (SUCCEEDED(hr))
{
*isDefault = false;
return resultMaybe;
diff --git a/src/tests/baseservices/RuntimeConfiguration/TestConfig.cs b/src/tests/baseservices/RuntimeConfiguration/TestConfig.cs
new file mode 100644
index 00000000000000..383a5d08f466d3
--- /dev/null
+++ b/src/tests/baseservices/RuntimeConfiguration/TestConfig.cs
@@ -0,0 +1,159 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using System.Runtime;
+
+using Xunit;
+
+class TestConfig
+{
+ const int Success = 100;
+ const int Fail = 101;
+
+ [Fact]
+ [EnvVar("DOTNET_gcServer", "1")]
+ static int Verify_ServerGC_Env_Enable(string[] _)
+ {
+ return GCSettings.IsServerGC
+ ? Success
+ : Fail;
+ }
+
+ [Fact]
+ [ConfigProperty("DOTNET_gcServer", "0")]
+ static int Verify_ServerGC_Env_Disable(string[] _)
+ {
+ return GCSettings.IsServerGC
+ ? Fail
+ : Success;
+ }
+
+ [Fact]
+ [ConfigProperty("System.GC.Server", "true")]
+ static int Verify_ServerGC_Prop_Enable(string[] _)
+ {
+ return GCSettings.IsServerGC
+ ? Success
+ : Fail;
+ }
+
+ [Fact]
+ [ConfigProperty("System.GC.Server", "false")]
+ static int Verify_ServerGC_Prop_Disable(string[] _)
+ {
+ return GCSettings.IsServerGC
+ ? Fail
+ : Success;
+ }
+
+ [Fact]
+ [EnvVar("DOTNET_gcServer", "0")]
+ [ConfigProperty("System.GC.Server", "true")]
+ static int Verify_ServerGC_Env_Override_Prop(string[] _)
+ {
+ return GCSettings.IsServerGC
+ ? Fail
+ : Success;
+ }
+
+ static int Main(string[] args)
+ {
+ if (args.Length == 0)
+ {
+ return RunTests();
+ }
+
+ MethodInfo infos = typeof(TestConfig).GetMethod(args[0], BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
+ if (infos is null)
+ {
+ return Fail;
+ }
+ return (int)infos.Invoke(null, new object[] { args[1..] });
+ }
+
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
+ class EnvVarAttribute : Attribute
+ {
+ public EnvVarAttribute(string name, string value) { Name = name; Value = value; }
+ public string Name { get; init; }
+ public string Value { get; init; }
+ }
+
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
+ class ConfigPropertyAttribute : Attribute
+ {
+ public ConfigPropertyAttribute(string name, string value) { Name = name; Value = value; }
+ public string Name { get; init; }
+ public string Value { get; init; }
+ }
+
+ static int RunTests()
+ {
+ string corerunPath = GetCorerunPath();
+ MethodInfo[] infos = typeof(TestConfig).GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
+ foreach (var mi in infos)
+ {
+ var factMaybe = mi.GetCustomAttributes(typeof(FactAttribute));
+ if (!factMaybe.Any())
+ {
+ continue;
+ }
+
+ using Process process = new();
+
+ StringBuilder arguments = new();
+ var configProperties = mi.GetCustomAttributes(typeof(ConfigPropertyAttribute));
+
+ foreach (Attribute cp in configProperties)
+ {
+ ConfigPropertyAttribute configProp = (ConfigPropertyAttribute)cp;
+ arguments.Append($"-p {configProp.Name}={configProp.Value} ");
+ }
+
+ arguments.Append($"\"{System.Reflection.Assembly.GetExecutingAssembly().Location}\" {mi.Name}");
+
+ process.StartInfo.FileName = corerunPath;
+ process.StartInfo.Arguments = arguments.ToString();
+
+ var envVariables = mi.GetCustomAttributes(typeof(EnvVarAttribute));
+ foreach (string key in Environment.GetEnvironmentVariables().Keys)
+ {
+ process.StartInfo.EnvironmentVariables[key] = Environment.GetEnvironmentVariable(key);
+ }
+
+ Console.WriteLine($"Running: {process.StartInfo.Arguments}");
+ foreach (Attribute ev in envVariables)
+ {
+ EnvVarAttribute envVar = (EnvVarAttribute)ev;
+ process.StartInfo.EnvironmentVariables[envVar.Name] = envVar.Value;
+ Console.WriteLine($" set {envVar.Name}={envVar.Value}");
+ }
+
+ process.Start();
+ process.WaitForExit();
+ if (process.ExitCode != Success)
+ {
+ Console.WriteLine($"Failed: {mi.Name}");
+ return process.ExitCode;
+ }
+ }
+
+ return Success;
+ }
+
+ static string GetCorerunPath()
+ {
+ string corerunName = "corerun";
+ if (TestLibrary.Utilities.IsWindows)
+ {
+ corerunName += ".exe";
+ }
+ return Path.Combine(Environment.GetEnvironmentVariable("CORE_ROOT"), corerunName);
+ }
+}
\ No newline at end of file
diff --git a/src/tests/baseservices/RuntimeConfiguration/TestConfig.csproj b/src/tests/baseservices/RuntimeConfiguration/TestConfig.csproj
new file mode 100644
index 00000000000000..efba9444477cd8
--- /dev/null
+++ b/src/tests/baseservices/RuntimeConfiguration/TestConfig.csproj
@@ -0,0 +1,15 @@
+
+
+ Exe
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/tests/issues.targets b/src/tests/issues.targets
index 29bf5fee8ffc4c..90f9fa90055d0e 100644
--- a/src/tests/issues.targets
+++ b/src/tests/issues.targets
@@ -987,6 +987,9 @@
Tests features specific to coreclr
+
+ Tests features specific to coreclr
+
https://github.com/dotnet/runtime/issues/40394