Forward ICLRSymbolProvider calls to a host-supplied symbol resolver#5877
Forward ICLRSymbolProvider calls to a host-supplied symbol resolver#5877max-charlamb wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR plumbs ClrMD’s symbol-resolution hook through the diagnostics host so both ClrMD’s data target and SOS’s legacy-DAC COM data target can resolve module-qualified symbols via a host-provided implementation. It also adjusts extension loading to proactively run module initializers and refactors some runtime-type/DAC selection logic.
Changes:
- Add a per-target
IClrSymbolProvideradapter over the host’s module/symbol services and pass it into ClrMD viaDataTargetOptions.SymbolProvider. - Expose
ICLRSymbolProvideron SOS’s legacy-DAC data-target CCW and forward calls to the sharedIClrSymbolProviderservice. - Run extension module initializers at load time; refactor runtime flavor→type mapping and add a CDAC fallback in
GetDacFilePath.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/SOS/SOS.Hosting/DataTargetWrapper.cs | Implements ICLRSymbolProvider on the legacy-DAC data target CCW and forwards symbol queries to a managed provider. |
| src/Microsoft.Diagnostics.DebugServices.Implementation/ServiceManager.cs | Forces module initializers to run when registering an extension assembly. |
| src/Microsoft.Diagnostics.DebugServices.Implementation/RuntimeProvider.cs | Supplies DataTargetOptions.SymbolProvider from the host service container when creating ClrMD DataTarget. |
| src/Microsoft.Diagnostics.DebugServices.Implementation/Runtime.cs | Centralizes flavor→RuntimeType mapping and adds a CDAC fallback path in GetDacFilePath. |
| src/Microsoft.Diagnostics.DebugServices.Implementation/HostSymbolProvider.cs | New adapter implementing ClrMD’s IClrSymbolProvider on top of IModuleService/IModuleSymbols. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Plumbs ClrMD's IClrSymbolProvider hook through the diagnostics host so the (c)DAC can map runtime addresses back to module-qualified symbols via the host's IModuleService / IModuleSymbols. Also unifies SOS's existing legacy-DAC symbol-provider thunks onto the same shared adapter. * HostSymbolProvider (new): IClrSymbolProvider adapter over IModuleService; registered as a per-target service via [ServiceExport]. * RuntimeProvider: sets DataTargetOptions.SymbolProvider from the registered service so ClrMD's COM data target wrapper forwards ICLRSymbolProvider calls to the host. * SOS.Hosting/DataTargetWrapper: exposes ICLRSymbolProvider on the legacy-DAC CCW (was missing), delegating to the same IClrSymbolProvider service for a single resolver code path. Aligns the CCW HRESULT contract with ClrMD's LegacyDacDataTargetWrapper (E_NOTIMPL when no provider, E_FAIL on miss, S_FALSE on truncation, null-terminated buffer, ! reserved as module separator). * Runtime: extracts the ClrFlavor -> RuntimeType mapping into a single GetRuntimeType helper; adds a generic GetDacFilePath fallback so runtimes that ship only a cDAC (no legacy DAC binary) load via the cDAC without the user having to set ForceUseContractReader. * IHostExtension (new) + ServiceManager: extension assemblies can implement IHostExtension to register process-wide state (e.g. a ClrMD IClrInfoProvider) at load time. Discovery is folded into the existing [ServiceExport]/[ProviderExport] type scan in RegisterExportedServices, so no new reflection pass is added. Depends on a ClrMD package that contains IClrSymbolProvider and DataTargetOptions.SymbolProvider (microsoft/clrmd#PR-merged; the package-version bump in eng/Version.Details.xml has landed via darc). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
5305ad6 to
2294a55
Compare
- HostSymbolProvider: remove unused System.IO using; fix XML doc (bare symbol names, qualifier stripped); inject IMemoryService and mask address/moduleBase via SignExtensionMask for x86 targets. - DataTargetWrapper.ICLRSymbolProvider: apply _ignoreAddressBitsMask to address/moduleBase for sign-extended x86 inputs (matches the pattern used by ReadVirtual/WriteVirtual in the same file). - ServiceManager.InvokeHostExtension: wrap Activator+Initialize and rethrow non-DiagnosticsException as DiagnosticsException so an extension constructor/initializer failure surfaces as a load failure instead of escaping RegisterAssembly. - IHostExtension: update doc to reflect per-implementing-type invocation (an assembly may contain multiple implementations; ordering is unspecified). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
leculver
left a comment
There was a problem hiding this comment.
Will take a look again tomorrow, just a quick skim so far.
| return false; | ||
| } | ||
|
|
||
| foreach (IModule module in _moduleService.EnumerateModules()) |
There was a problem hiding this comment.
Do we even want to support moduleBase == 0? To scan everything? Once we reach here this is going to grind the entire debugger to an absolute halt, and with no cancellation token possible across com, this is going to be pure pain.
Requires: microsoft/clrmd#1482
Plumbs ClrMD's IClrSymbolProvider hook through the diagnostics host so the (c)DAC can map runtime addresses back to module-qualified symbols via the host's IModuleService / IModuleSymbols. Also unifies SOS's existing legacy-DAC symbol-provider thunks onto the same shared adapter.
HostSymbolProvider (new): IClrSymbolProvider adapter over IModuleService; registered as a per-target service via [ServiceExport].
RuntimeProvider: sets DataTargetOptions.SymbolProvider from the registered service so ClrMD's COM data target wrapper forwards ICLRSymbolProvider calls to the host.
SOS.Hosting/DataTargetWrapper: exposes ICLRSymbolProvider on the legacy-DAC CCW (was missing), delegating to the same IClrSymbolProvider service for a single resolver code path.
Runtime: extracts the ClrFlavor -> RuntimeType mapping into a single GetRuntimeType helper; adds a generic GetDacFilePath fallback so runtimes that ship only a cDAC (no legacy DAC binary) load via the cDAC without the user having to set ForceUseContractReader.
ServiceManager: invokes RuntimeHelpers.RunModuleConstructor on each loaded extension so module initializers fire at load time, allowing extensions to register process-wide state (e.g. ClrMD IClrInfoProvider) before any provider factory is invoked.
Depends on a ClrMD package that contains IClrSymbolProvider and DataTargetOptions.SymbolProvider (microsoft/clrmd PR pending; the corresponding package-version bump in eng/Version.Details.xml will land via darc once the upstream PR merges).