Exploring the .NET Boot Process via Host Tracing
Andrew Lock provides a technical walkthrough exploring .NET’s boot process using host tracing, offering developers step-by-step insights into muxer, hostfxr, and hostpolicy.dll components.
Exploring the .NET Boot Process via Host Tracing
Enabling host tracing is a powerful way to diagnose issues with .NET application startup. Andrew Lock explains how to activate this feature and leverage detailed logs to understand the chain of processes—from running a simple console app, to execution via the dotnet muxer, to hostfxr’s runtime selection, and hostpolicy.dll’s role in loading assemblies and launching CoreCLR.
1. Enabling Host Tracing
Set the following environment variables to enable tracing:
COREHOST_TRACE=1(activates tracing and logs to stderr by default)COREHOST_TRACEFILE=<file_path>(redirects logs to a file)- For .NET 10+, you can also point to a directory; the trace will be saved by exe and PID.
- Adjust verbosity using
COREHOST_TRACE_VERBOSITY=<level>(1 = errors, 4 = verbose)
Example PowerShell:
$env:COREHOST_TRACE=1
$env:COREHOST_TRACEFILE="host_trace.log"
dotnet bin\Debug\net9.0\MyApp.dll
2. .NET Boot Process Components
dotnet muxer
- Entry point for .NET commands (build, publish, run).
- Located at
C:\Program Files\dotnet\dotnet.exe. - Determines if you’re running an SDK command or an app.
- Loads the latest
hostfxrversion based on SemVer from.../host/fxrfolder.
hostfxr
- Parses arguments to distinguish between SDK commands and app execution.
- Locates SDK via
global.jsonand roll-forward policy, or resolves app runtime fromruntimeconfig.json. - Finds and loads
hostpolicy.dllfor chosen runtime and framework.
hostpolicy
- Compiles the list of Trusted Platform Assemblies (TPA) from framework and app deps.json files.
- Sets up process context (environment properties, probing directories, config properties).
- Loads and launches the .NET runtime via
coreclr.dll.
3. Reading the Host Tracing Logs
Tracing logs show how components select versions, validate configs, and load libraries. Example traces help diagnose issues like missing runtime versions, incorrect SDK selection, or asset loading errors.
Sample log excerpt (boot chain):
Invoked dotnet [version: 10.0.0-rc.2...]
Considering fxr version=[10.0.0-rc.2...]
Resolved fxr [hostfxr.dll]... Loaded library...
Invoking fx resolver...
Probing for global.json... Resolving SDK...
App runtimeconfig.json found, version established...
Roll forward enabled...
Chose FX version [Microsoft.NETCore.App\9.0.10]
Loaded library from [hostpolicy.dll]
Processing package...
Adding tpa entry: myapp.dll, System.Private.CoreLib.dll...
Loaded library from [coreclr.dll]
Launch host: dotnet.exe, app: myapp.dll
4. Diagnosing Boot Issues
- Use tracing output to see why an app is loading an unexpected .NET version.
- Validate existence and correctness of runtimeconfig.json and deps.json.
- Check roll-forward policies to troubleshoot version mismatches.
- Confirm that all required assemblies and native assets are present and loaded.
5. Summary
Host tracing demystifies the .NET app launch sequence, exposing hidden details about runtime and SDK selection, dependency loading, and execution context setup. This approach is invaluable for diagnosing startup problems and understanding the internals of the .NET host.
Author: Andrew Lock
For further reading about internals, see Steve Gordon’s posts on the dotnet muxer and hostfxr library.
This post appeared first on “Andrew Lock’s Blog”. Read the entire article here