Skip to content

Commit 7195086

Browse files
authored
Check DOTNET_HOST_* for host (COREHOST_*) tracing environment variables (#117894)
Respect the `DOTNET_` prefix for `COREHOST_` environment variables as a move toward greater consistency for .NET environment variables
1 parent 1b243b7 commit 7195086

File tree

5 files changed

+60
-57
lines changed

5 files changed

+60
-57
lines changed

src/installer/tests/HostActivation.Tests/HostVersionCompatibility.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ private void OldHost_LatestRuntime_ForwardCompatible(TestApp previousVersionApp)
8080
// 2) App rolls forward to newer runtime
8181
File.Copy(previousVersionApp.AppExe, appExe, true);
8282
Command.Create(appExe)
83-
.EnableTracingAndCaptureOutputs()
83+
.CaptureStdOut().CaptureStdErr()
84+
.EnvironmentVariable("COREHOST_TRACE", "1") // Old host, so we need to use the old variable name
8485
.Execute()
8586
.Should().Pass()
8687
.And.HaveStdOutContaining("Hello World")
@@ -95,7 +96,8 @@ private void OldHost_LatestRuntime_ForwardCompatible(TestApp previousVersionApp)
9596
{
9697
File.Copy(previousVersionApp.HostFxrDll, app.HostFxrDll, true);
9798
Command.Create(appExe)
98-
.EnableTracingAndCaptureOutputs()
99+
.CaptureStdOut().CaptureStdErr()
100+
.EnvironmentVariable("COREHOST_TRACE", "1") // Old host, so we need to use the old variable name
99101
.Execute()
100102
.Should().Pass()
101103
.And.HaveStdOutContaining("Hello World")

src/installer/tests/HostActivation.Tests/Tracing.cs

Lines changed: 22 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,18 @@
77

88
namespace Microsoft.DotNet.CoreSetup.Test.HostActivation
99
{
10-
public class Tracing : IClassFixture<Tracing.SharedTestState>
10+
public class Tracing
1111
{
12-
private SharedTestState sharedTestState;
12+
// Trace messages currently expected for running dotnet --list-runtimes
13+
private const string ExpectedVerboseMessage = "--- Executing in muxer mode";
14+
private const string ExpectedInfoMessage = "--- Invoked dotnet";
1315

14-
// Trace messages currently expected for a passing app (somewhat randomly selected)
15-
private const string ExpectedVerboseMessage = "--- Begin breadcrumb write";
16-
private const string ExpectedInfoMessage = "Deps file:";
17-
private const string ExpectedBadPathMessage = "Unable to open COREHOST_TRACEFILE=";
18-
19-
public Tracing(Tracing.SharedTestState fixture)
20-
{
21-
sharedTestState = fixture;
22-
}
16+
private const string ExpectedBadPathMessage = "Unable to open specified trace file for writing:";
2317

2418
[Fact]
2519
public void TracingOff()
2620
{
27-
TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll)
21+
TestContext.BuiltDotNet.Exec("--list-runtimes")
2822
.CaptureStdOut()
2923
.CaptureStdErr()
3024
.Execute()
@@ -36,66 +30,60 @@ public void TracingOff()
3630
[Fact]
3731
public void TracingOnDefault()
3832
{
39-
TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll)
33+
TestContext.BuiltDotNet.Exec("--list-runtimes")
4034
.EnableTracingAndCaptureOutputs()
4135
.Execute()
4236
.Should().Pass()
43-
.And.HaveStdOutContaining("Hello World")
4437
.And.HaveStdErrContaining(ExpectedInfoMessage)
4538
.And.HaveStdErrContaining(ExpectedVerboseMessage);
4639
}
4740

4841
[Fact]
4942
public void TracingOnVerbose()
5043
{
51-
TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll)
44+
TestContext.BuiltDotNet.Exec("--list-runtimes")
5245
.EnableTracingAndCaptureOutputs()
5346
.EnvironmentVariable(Constants.HostTracing.VerbosityEnvironmentVariable, "4")
5447
.Execute()
5548
.Should().Pass()
56-
.And.HaveStdOutContaining("Hello World")
5749
.And.HaveStdErrContaining(ExpectedInfoMessage)
5850
.And.HaveStdErrContaining(ExpectedVerboseMessage);
5951
}
6052

6153
[Fact]
6254
public void TracingOnInfo()
6355
{
64-
TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll)
56+
TestContext.BuiltDotNet.Exec("--list-runtimes")
6557
.EnableTracingAndCaptureOutputs()
6658
.EnvironmentVariable(Constants.HostTracing.VerbosityEnvironmentVariable, "3")
6759
.Execute()
6860
.Should().Pass()
69-
.And.HaveStdOutContaining("Hello World")
7061
.And.HaveStdErrContaining(ExpectedInfoMessage)
7162
.And.NotHaveStdErrContaining(ExpectedVerboseMessage);
7263
}
7364

7465
[Fact]
7566
public void TracingOnWarning()
7667
{
77-
TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll)
68+
TestContext.BuiltDotNet.Exec("--list-runtimes")
7869
.EnableTracingAndCaptureOutputs()
7970
.EnvironmentVariable(Constants.HostTracing.VerbosityEnvironmentVariable, "2")
8071
.Execute()
8172
.Should().Pass()
82-
.And.HaveStdOutContaining("Hello World")
8373
.And.NotHaveStdErrContaining(ExpectedInfoMessage)
8474
.And.NotHaveStdErrContaining(ExpectedVerboseMessage);
8575
}
8676

8777
[Fact]
8878
public void TracingOnToFileDefault()
8979
{
90-
9180
string traceFilePath;
92-
TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll)
81+
TestContext.BuiltDotNet.Exec("--list-runtimes")
9382
.EnableHostTracingToFile(out traceFilePath)
9483
.CaptureStdOut()
9584
.CaptureStdErr()
9685
.Execute()
9786
.Should().Pass()
98-
.And.HaveStdOutContaining("Hello World")
9987
.And.NotHaveStdErrContaining(ExpectedInfoMessage)
10088
.And.NotHaveStdErrContaining(ExpectedVerboseMessage)
10189
.And.FileExists(traceFilePath)
@@ -107,12 +95,11 @@ public void TracingOnToFileDefault()
10795
[Fact]
10896
public void TracingOnToFileBadPathDefault()
10997
{
110-
TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll)
98+
TestContext.BuiltDotNet.Exec("--list-runtimes")
11199
.EnableTracingAndCaptureOutputs()
112100
.EnvironmentVariable(Constants.HostTracing.TraceFileEnvironmentVariable, "badpath/TracingOnToFileBadPathDefault.log")
113101
.Execute()
114102
.Should().Pass()
115-
.And.HaveStdOutContaining("Hello World")
116103
.And.HaveStdErrContaining(ExpectedInfoMessage)
117104
.And.HaveStdErrContaining(ExpectedVerboseMessage)
118105
.And.HaveStdErrContaining(ExpectedBadPathMessage);
@@ -123,36 +110,31 @@ public void TracingOnToDirectory()
123110
{
124111
using (TestArtifact directory = TestArtifact.Create("trace"))
125112
{
126-
var result = TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll)
113+
var result = TestContext.BuiltDotNet.Exec("--list-runtimes")
127114
.EnableHostTracingToPath(directory.Location)
128115
.CaptureStdOut()
129116
.CaptureStdErr()
130117
.Execute();
131118

132119
string traceFilePath = Path.Combine(directory.Location, $"{Path.GetFileNameWithoutExtension(Binaries.DotNet.FileName)}.{result.ProcessId}.log");
133120
result.Should().Pass()
134-
.And.HaveStdOutContaining("Hello World")
135121
.And.NotHaveStdErrContaining(ExpectedInfoMessage)
136122
.And.NotHaveStdErrContaining(ExpectedVerboseMessage)
137123
.And.FileExists(traceFilePath)
138124
.And.FileContains(traceFilePath, ExpectedVerboseMessage);
139125
}
140126
}
141127

142-
public class SharedTestState : IDisposable
128+
[Fact]
129+
public void LegacyVariableName()
143130
{
144-
public TestApp App { get; }
145-
146-
public SharedTestState()
147-
{
148-
App = TestApp.CreateFromBuiltAssets("HelloWorld");
149-
App.CreateAppHost();
150-
}
151-
152-
public void Dispose()
153-
{
154-
App?.Dispose();
155-
}
131+
TestContext.BuiltDotNet.Exec("--list-runtimes")
132+
.EnvironmentVariable("COREHOST_TRACE", "1")
133+
.CaptureStdErr()
134+
.Execute()
135+
.Should().Pass()
136+
.And.HaveStdErrContaining(ExpectedInfoMessage)
137+
.And.HaveStdErrContaining(ExpectedVerboseMessage);
156138
}
157139
}
158140
}

src/installer/tests/TestUtils/Constants.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ public static class MultilevelLookup
103103

104104
public static class HostTracing
105105
{
106-
public const string TraceLevelEnvironmentVariable = "COREHOST_TRACE";
107-
public const string TraceFileEnvironmentVariable = "COREHOST_TRACEFILE";
108-
public const string VerbosityEnvironmentVariable = "COREHOST_TRACE_VERBOSITY";
106+
public const string TraceLevelEnvironmentVariable = "DOTNET_HOST_TRACE";
107+
public const string TraceFileEnvironmentVariable = "DOTNET_HOST_TRACEFILE";
108+
public const string VerbosityEnvironmentVariable = "DOTNET_HOST_TRACE_VERBOSITY";
109109
}
110110

111111
public static class DotnetRoot

src/native/corehost/hostmisc/trace.cpp

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212
#define TRACE_VERBOSITY_INFO 3
1313
#define TRACE_VERBOSITY_VERBOSE 4
1414

15-
// g_trace_verbosity is used to encode COREHOST_TRACE and COREHOST_TRACE_VERBOSITY to selectively control output of
15+
// g_trace_verbosity is used to encode DOTNET_HOST_TRACE and DOTNET_HOST_TRACE_VERBOSITY to selectively control output of
1616
// trace::warn(), trace::info(), and trace::verbose()
17-
// COREHOST_TRACE=0 COREHOST_TRACE_VERBOSITY=N/A implies g_trace_verbosity = 0. // Trace "disabled". error() messages will be produced.
18-
// COREHOST_TRACE=1 COREHOST_TRACE_VERBOSITY=4 or unset implies g_trace_verbosity = 4. // Trace "enabled". verbose(), info(), warn() and error() messages will be produced
19-
// COREHOST_TRACE=1 COREHOST_TRACE_VERBOSITY=3 implies g_trace_verbosity = 3. // Trace "enabled". info(), warn() and error() messages will be produced
20-
// COREHOST_TRACE=1 COREHOST_TRACE_VERBOSITY=2 implies g_trace_verbosity = 2. // Trace "enabled". warn() and error() messages will be produced
21-
// COREHOST_TRACE=1 COREHOST_TRACE_VERBOSITY=1 implies g_trace_verbosity = 1. // Trace "enabled". error() messages will be produced
17+
// DOTNET_HOST_TRACE=0 DOTNET_HOST_TRACE_VERBOSITY=N/A implies g_trace_verbosity = 0. // Trace "disabled". error() messages will be produced.
18+
// DOTNET_HOST_TRACE=1 DOTNET_HOST_TRACE_VERBOSITY=4 or unset implies g_trace_verbosity = 4. // Trace "enabled". verbose(), info(), warn() and error() messages will be produced
19+
// DOTNET_HOST_TRACE=1 DOTNET_HOST_TRACE_VERBOSITY=3 implies g_trace_verbosity = 3. // Trace "enabled". info(), warn() and error() messages will be produced
20+
// DOTNET_HOST_TRACE=1 DOTNET_HOST_TRACE_VERBOSITY=2 implies g_trace_verbosity = 2. // Trace "enabled". warn() and error() messages will be produced
21+
// DOTNET_HOST_TRACE=1 DOTNET_HOST_TRACE_VERBOSITY=1 implies g_trace_verbosity = 1. // Trace "enabled". error() messages will be produced
2222
static int g_trace_verbosity = 0;
2323
static FILE * g_trace_file = nullptr;
2424
thread_local static trace::error_writer_fn g_error_writer = nullptr;
@@ -52,16 +52,35 @@ namespace
5252
};
5353

5454
spin_lock g_trace_lock;
55+
56+
template<size_t NameLen>
57+
bool get_host_env_var(const pal::char_t (&name)[NameLen], pal::string_t* value)
58+
{
59+
assert(name[NameLen - 1] == _X('\0')); // name is expected to be null-terminated
60+
61+
// DOTNET_HOST_* takes precedence
62+
constexpr size_t dotnet_host_prefix_len = STRING_LENGTH("DOTNET_HOST_");
63+
pal::char_t dotnet_host_name[dotnet_host_prefix_len + NameLen];
64+
pal::snwprintf(dotnet_host_name, ARRAY_SIZE(dotnet_host_name), _X("DOTNET_HOST_%s"), name);
65+
if (pal::getenv(dotnet_host_name, value))
66+
return true;
67+
68+
// COREHOST_* for backwards compatibility
69+
constexpr size_t corehost_prefix_len = STRING_LENGTH("COREHOST_");
70+
pal::char_t corehost_name[corehost_prefix_len + NameLen];
71+
pal::snwprintf(corehost_name, ARRAY_SIZE(corehost_name), _X("COREHOST_%s"), name);
72+
return pal::getenv(corehost_name, value);
73+
}
5574
}
5675

5776
//
58-
// Turn on tracing for the corehost based on "COREHOST_TRACE" & "COREHOST_TRACEFILE" env.
77+
// Turn on tracing for the corehost based on "DOTNET_HOST_TRACE" & "DOTNET_HOST_TRACEFILE" env.
5978
//
6079
void trace::setup()
6180
{
6281
// Read trace environment variable
6382
pal::string_t trace_str;
64-
if (!pal::getenv(_X("COREHOST_TRACE"), &trace_str))
83+
if (!get_host_env_var(_X("TRACE"), &trace_str))
6584
{
6685
return;
6786
}
@@ -91,7 +110,7 @@ bool trace::enable()
91110
std::lock_guard<spin_lock> lock(g_trace_lock);
92111

93112
g_trace_file = stderr; // Trace to stderr by default
94-
if (pal::getenv(_X("COREHOST_TRACEFILE"), &tracefile_str))
113+
if (get_host_env_var(_X("TRACEFILE"), &tracefile_str))
95114
{
96115
if (pal::is_directory(tracefile_str))
97116
{
@@ -122,7 +141,7 @@ bool trace::enable()
122141
}
123142

124143
pal::string_t trace_str;
125-
if (!pal::getenv(_X("COREHOST_TRACE_VERBOSITY"), &trace_str))
144+
if (!get_host_env_var(_X("TRACE_VERBOSITY"), &trace_str))
126145
{
127146
g_trace_verbosity = TRACE_VERBOSITY_VERBOSE; // Verbose trace by default
128147
}
@@ -134,7 +153,7 @@ bool trace::enable()
134153

135154
if (file_open_error)
136155
{
137-
trace::error(_X("Unable to open COREHOST_TRACEFILE=%s for writing"), tracefile_str.c_str());
156+
trace::error(_X("Unable to open specified trace file for writing: %s"), tracefile_str.c_str());
138157
}
139158
return true;
140159
}

src/native/corehost/hostpolicy/hostpolicy_context.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ int hostpolicy_context_t::initialize(const hostpolicy_init_t &hostpolicy_init, c
224224
// otherwise fail early.
225225
if (!bundle::info_t::is_single_file_bundle())
226226
{
227-
trace::error(_X("Could not resolve CoreCLR path. For more details, enable tracing by setting COREHOST_TRACE environment variable to 1"));
227+
trace::error(_X("Could not resolve CoreCLR path. For more details, enable tracing by setting DOTNET_HOST_TRACE environment variable to 1"));
228228
return StatusCode::CoreClrResolveFailure;
229229
}
230230

0 commit comments

Comments
 (0)