From 29deb1edef5db2dd3dea44437c77913ae22dce40 Mon Sep 17 00:00:00 2001 From: Max Charlamb Date: Fri, 17 Apr 2026 13:59:24 -0400 Subject: [PATCH 1/3] [cDAC] Implement GetMethodDefinitionByToken in ClrDataModule Implement IXCLRDataModule.GetMethodDefinitionByToken in the cDAC ClrDataModule wrapper instead of delegating entirely to the legacy DAC. The implementation validates the token is an mdtMethodDef, retrieves the legacy method definition for DEBUG parity validation, and creates a ClrDataMethodDefinition with the token and module address. This follows the same pattern used by EnumMethodDefinitionByName and enables removing GetMethodDefinitionByToken from the cDAC no-fallback allowlist. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../ClrDataModule.cs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataModule.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataModule.cs index 38047994bffbef..5467735eaa0319 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataModule.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataModule.cs @@ -355,7 +355,38 @@ int IXCLRDataModule.EndEnumMethodInstancesByName(ulong handle) => LegacyFallbackHelper.CanFallback() && _legacyModule is not null ? _legacyModule.EndEnumMethodInstancesByName(handle) : HResults.E_NOTIMPL; int IXCLRDataModule.GetMethodDefinitionByToken(/*mdMethodDef*/ uint token, DacComNullableByRef methodDefinition) - => LegacyFallbackHelper.CanFallback() && _legacyModule is not null ? _legacyModule.GetMethodDefinitionByToken(token, methodDefinition) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + int hrLocal = HResults.S_OK; + IXCLRDataMethodDefinition? legacyMethod = null; + try + { + if (_legacyModule is not null) + { + DacComNullableByRef legacyMethodOut = new(isNullRef: false); + hrLocal = _legacyModule.GetMethodDefinitionByToken(token, legacyMethodOut); + legacyMethod = legacyMethodOut.Interface; + } + + if ((EcmaMetadataUtils.TokenType)(token & EcmaMetadataUtils.TokenTypeMask) != EcmaMetadataUtils.TokenType.mdtMethodDef) + throw new ArgumentException(); + + methodDefinition.Interface = new ClrDataMethodDefinition(_target, _address, token, legacyMethod); + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + +#if DEBUG + if (_legacyModule is not null) + { + Debug.ValidateHResult(hr, hrLocal); + } +#endif + + return hr; + } int IXCLRDataModule.StartEnumDataByName(char* name, uint flags, IXCLRDataAppDomain? appDomain, IXCLRDataTask? tlsTask, ulong* handle) => LegacyFallbackHelper.CanFallback() && _legacyModule is not null ? _legacyModule.StartEnumDataByName(name, flags, appDomain, tlsTask, handle) : HResults.E_NOTIMPL; From e67c1fb1e1868359a10e9f62809edd88750f2dec Mon Sep 17 00:00:00 2001 From: Max Charlamb Date: Fri, 17 Apr 2026 17:33:52 -0400 Subject: [PATCH 2/3] Remove GetMethodDefinitionByToken from no-fallback allowlist Now that GetMethodDefinitionByToken is implemented in the cDAC, it no longer needs to be in the LegacyFallbackHelper allowlist. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../LegacyFallbackHelper.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/LegacyFallbackHelper.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/LegacyFallbackHelper.cs index 52116e5130f19c..2f4d5c07a4d03e 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/LegacyFallbackHelper.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/LegacyFallbackHelper.cs @@ -29,9 +29,6 @@ internal static class LegacyFallbackHelper // IMetaDataImport QI — needed until managed MetadataReader wrapper lands (PR #127028). nameof(ICustomQueryInterface.GetInterface), - // IXCLRDataModule — not yet implemented in the cDAC. - nameof(IXCLRDataModule.GetMethodDefinitionByToken), - // GC heap analysis — not yet implemented in the cDAC (PR #125895). nameof(ISOSDacInterface11.IsTrackedType), From 913a2a75356eb7fce01feafa7eb573a549a32fd8 Mon Sep 17 00:00:00 2001 From: Max Charlamb Date: Fri, 17 Apr 2026 20:46:46 -0400 Subject: [PATCH 3/3] Add ClrDataMethodDefinition methods to no-fallback allowlist GetMethodDefinitionByToken now returns a cDAC-managed ClrDataMethodDefinition wrapper. When SOS calls methods on it, those delegate to legacy but are blocked by the no-fallback check. Add the four downstream methods that are not yet implemented in the cDAC: - StartEnumInstances - GetName - SetCodeNotification - HasClassOrMethodInstantiation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../LegacyFallbackHelper.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/LegacyFallbackHelper.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/LegacyFallbackHelper.cs index 2f4d5c07a4d03e..8b577e093a6eea 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/LegacyFallbackHelper.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/LegacyFallbackHelper.cs @@ -34,6 +34,12 @@ internal static class LegacyFallbackHelper // Loader heap traversal — not yet implemented in the cDAC (PR #125129). nameof(ISOSDacInterface.TraverseLoaderHeap), + + // IXCLRDataMethodDefinition — not yet implemented in the cDAC. + nameof(IXCLRDataMethodDefinition.StartEnumInstances), + nameof(IXCLRDataMethodDefinition.GetName), + nameof(IXCLRDataMethodDefinition.SetCodeNotification), + nameof(IXCLRDataMethodDefinition.HasClassOrMethodInstantiation), }; // Files whose methods are all allowed to fall back.