From ee4263a62f8eef2702de1befcea17919fbc05bea Mon Sep 17 00:00:00 2001 From: rcj1 Date: Mon, 4 Aug 2025 17:45:22 -0700 Subject: [PATCH 1/7] adding GetComWrappersRCWData cDAC API --- docs/design/datacontracts/Object.md | 13 +++++++ .../datacontracts/debug_interface_globals.md | 1 + .../debug/runtimeinfo/datadescriptor.cpp | 1 + .../debug/runtimeinfo/datadescriptor.inc | 10 +++++ .../vm/interoplibinterface_comwrappers.h | 9 +++++ .../Contracts/IObject.cs | 1 + .../DataType.cs | 1 + .../Constants.cs | 1 + .../Contracts/Object_1.cs | 10 +++++ .../Data/NativeObjectWrapperObject.cs | 18 +++++++++ .../Legacy/SOSDacImpl.cs | 37 ++++++++++++++++++- 11 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/NativeObjectWrapperObject.cs diff --git a/docs/design/datacontracts/Object.md b/docs/design/datacontracts/Object.md index 18747df027df3c..a964f7d56d7ef6 100644 --- a/docs/design/datacontracts/Object.md +++ b/docs/design/datacontracts/Object.md @@ -16,6 +16,9 @@ TargetPointer GetArrayData(TargetPointer address, out uint count, out TargetPoin // Get built-in COM data for the object if available. Returns false, if address does not represent a COM object using built-in COM bool GetBuiltInComData(TargetPointer address, out TargetPointer rcw, out TargetPointer ccw); + +// Get the address of the external COM object +TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw); ``` ## Version 1 @@ -31,6 +34,7 @@ Data descriptors used: | `String` | `m_StringLength` | Length of the string in characters (encoded in UTF-16) | | `SyncBlock` | `InteropInfo` | Optional `InteropSyncBlockInfo` for the sync block | | `SyncTableEntry` | `SyncBlock` | `SyncBlock` corresponding to the entry | +| `NativeObjectWrapperObject` | `ExternalComObject` | Address of the external COM object | Global variables used: | Global Name | Type | Purpose | @@ -125,4 +129,13 @@ bool GetBuiltInComData(TargetPointer address, out TargetPointer rcw, out TargetP ccw = target.ReadPointer(interopInfo + /* InteropSyncBlockInfo::CCW offset */); return rcw != TargetPointer.Null && ccw != TargetPointer.Null; } + +TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw) +{ + if ((rcw.Value & 1) == 0) + { + return TargetPointer.Null; + } + return target.ReadPointer(new TargetPointer(rcw.Value & ~1UL) + /* NativeObjectWrapperObject::ExternalComObject offset */); +} ``` diff --git a/docs/design/datacontracts/debug_interface_globals.md b/docs/design/datacontracts/debug_interface_globals.md index c4d1348f138ce0..f36acaff88f7aa 100644 --- a/docs/design/datacontracts/debug_interface_globals.md +++ b/docs/design/datacontracts/debug_interface_globals.md @@ -20,3 +20,4 @@ Global variables used | MaxClrNotificationArgs | uint32 | Identify the maximum number of CLR notification arguments | | ClrNotificationArguments | TargetPointer | Identify where the ClrNotificationArguments exists | | DefaultADID | uint | Identify the default AppDomain ID | +| FeatureCOMWrappers | uint8 | Flag for if FeatureCOMWrappers is disabled (0) or enabled (1) | diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.cpp b/src/coreclr/debug/runtimeinfo/datadescriptor.cpp index 0efae1ad25089f..0868b4880718ed 100644 --- a/src/coreclr/debug/runtimeinfo/datadescriptor.cpp +++ b/src/coreclr/debug/runtimeinfo/datadescriptor.cpp @@ -13,6 +13,7 @@ #include "methodtable.h" #include "threads.h" #include "exinfo.h" +#include "interoplibinterface_comwrappers.h" #include "configure.h" diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.inc b/src/coreclr/debug/runtimeinfo/datadescriptor.inc index 250ac0f4f9a95b..437a821abefc8a 100644 --- a/src/coreclr/debug/runtimeinfo/datadescriptor.inc +++ b/src/coreclr/debug/runtimeinfo/datadescriptor.inc @@ -214,6 +214,11 @@ CDAC_TYPE_INDETERMINATE(SyncBlock) CDAC_TYPE_FIELD(SyncBlock, /*pointer*/, InteropInfo, cdac_data::InteropInfo) CDAC_TYPE_END(SyncBlock) +CDAC_TYPE_BEGIN(NativeObjectWrapperObject) +CDAC_TYPE_INDETERMINATE(NativeObjectWrapperObject) +CDAC_TYPE_FIELD(NativeObjectWrapperObject, /*pointer*/, ExternalComObject, cdac_data::ExternalComObject) +CDAC_TYPE_END(NativeObjectWrapperObject) + CDAC_TYPE_BEGIN(SyncTableEntry) CDAC_TYPE_SIZE(sizeof(SyncTableEntry)) CDAC_TYPE_FIELD(SyncTableEntry, /*pointer*/, SyncBlock, offsetof(SyncTableEntry, m_SyncBlock)) @@ -970,6 +975,11 @@ CDAC_GLOBAL(FeatureCOMInterop, uint8, 1) #else CDAC_GLOBAL(FeatureCOMInterop, uint8, 0) #endif +#if FEATURE_COMWRAPPERS +CDAC_GLOBAL(FeatureCOMWrappers, uint8, 1) +#else +CDAC_GLOBAL(FeatureCOMWrappers, uint8, 0) +#endif // See Object::GetGCSafeMethodTable #ifdef TARGET_64BIT CDAC_GLOBAL(ObjectToMethodTableUnmask, uint8, 1 | 1 << 1 | 1 << 2) diff --git a/src/coreclr/vm/interoplibinterface_comwrappers.h b/src/coreclr/vm/interoplibinterface_comwrappers.h index 763ada50190f1f..ce19830fa98119 100644 --- a/src/coreclr/vm/interoplibinterface_comwrappers.h +++ b/src/coreclr/vm/interoplibinterface_comwrappers.h @@ -9,6 +9,7 @@ #define _INTEROPLIBINTERFACE_COMWRAPPERS_H_ #include +#include "cdacdata.h" // Native calls for the managed ComWrappers API class ComWrappersNative @@ -98,6 +99,14 @@ class NativeObjectWrapperObject : public Object { return _externalComObject; } + + friend struct ::cdac_data; +}; + +template<> +struct cdac_data +{ + static constexpr size_t ExternalComObject = offsetof(NativeObjectWrapperObject, _externalComObject); }; class ReferenceTrackerNativeObjectWrapperObject final : public NativeObjectWrapperObject diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IObject.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IObject.cs index 7566ddacc1e488..37e040f6099382 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IObject.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IObject.cs @@ -12,6 +12,7 @@ public interface IObject : IContract string GetStringValue(TargetPointer address) => throw new NotImplementedException(); TargetPointer GetArrayData(TargetPointer address, out uint count, out TargetPointer boundsStart, out TargetPointer lowerBounds) => throw new NotImplementedException(); bool GetBuiltInComData(TargetPointer address, out TargetPointer rcw, out TargetPointer ccw) => throw new NotImplementedException(); + TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw) => throw new NotImplementedException(); } public readonly struct Object : IObject diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs index 98ead3efdd2fdf..70d740a38b6477 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs @@ -59,6 +59,7 @@ public enum DataType StressMsg, StressMsgHeader, Object, + NativeObjectWrapperObject, String, MethodDesc, MethodDescChunk, diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs index c5a2dbacecb8e0..edd259c31e0fb0 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs @@ -15,6 +15,7 @@ public static class Globals public const string GCThread = nameof(GCThread); public const string FeatureCOMInterop = nameof(FeatureCOMInterop); + public const string FeatureCOMWrappers = nameof(FeatureCOMWrappers); public const string ObjectToMethodTableUnmask = nameof(ObjectToMethodTableUnmask); public const string SOSBreakingChangeVersion = nameof(SOSBreakingChangeVersion); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs index d35b683f028fb1..02b89046cd4658 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs @@ -129,4 +129,14 @@ public bool GetBuiltInComData(TargetPointer address, out TargetPointer rcw, out Data.SyncTableEntry entry = _target.ProcessedData.GetOrAdd(_syncTableEntries + offsetInSyncTableEntries); return entry.SyncBlock; } + + public TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw) + { + if ((rcw.Value & 1) == 0) + { + return TargetPointer.Null; // Invalid RCW address + } + Data.NativeObjectWrapperObject wrapper = _target.ProcessedData.GetOrAdd(rcw.Value & ~1UL); + return wrapper.ExternalComObject; + } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/NativeObjectWrapperObject.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/NativeObjectWrapperObject.cs new file mode 100644 index 00000000000000..f1d61ef69559ec --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/NativeObjectWrapperObject.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class NativeObjectWrapperObject : IData +{ + static NativeObjectWrapperObject IData.Create(Target target, TargetPointer address) => new NativeObjectWrapperObject(target, address); + public NativeObjectWrapperObject(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.NativeObjectWrapperObject); + ExternalComObject = target.ReadPointer(address + (ulong)type.Fields[nameof(ExternalComObject)].Offset); + } + + public TargetPointer ExternalComObject { get; init; } +} diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs index b1cc4cc1ac9d24..e60103aaa87ed5 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs @@ -2371,7 +2371,42 @@ int ISOSDacInterface10.GetComWrappersCCWData(ClrDataAddress ccw, ClrDataAddress* int ISOSDacInterface10.IsComWrappersRCW(ClrDataAddress rcw, Interop.BOOL* isComWrappersRCW) => _legacyImpl10 is not null ? _legacyImpl10.IsComWrappersRCW(rcw, isComWrappersRCW) : HResults.E_NOTIMPL; int ISOSDacInterface10.GetComWrappersRCWData(ClrDataAddress rcw, ClrDataAddress* identity) - => _legacyImpl10 is not null ? _legacyImpl10.GetComWrappersRCWData(rcw, identity) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + if (_target.ReadGlobalPointer(Constants.Globals.FeatureCOMWrappers) == 0) + hr = HResults.E_NOTIMPL; + else if (rcw == 0) + hr = HResults.E_INVALIDARG; + else + { + try + { + if (identity != null) + { + Contracts.IObject objectContract = _target.Contracts.Object; + TargetPointer identityPtr = objectContract.GetComWrappersRCWIdentity(rcw.ToTargetPointer(_target)); + *identity = identityPtr.ToClrDataAddress(_target); + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + } +#if DEBUG + if (_legacyImpl10 is not null) + { + ClrDataAddress identityLocal; + int hrLocal = _legacyImpl10.GetComWrappersRCWData(rcw, &identityLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(*identity == identityLocal); + } + } +#endif + return hr; + } #endregion ISOSDacInterface10 #region ISOSDacInterface11 From 0c09c3c8ff02c8c0e47e36049fa86fb98f4eb0b1 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Thu, 7 Aug 2025 08:29:05 -0700 Subject: [PATCH 2/7] t --- docs/design/datacontracts/ComWrappers.md | 54 +++++++++++++++++++ docs/design/datacontracts/Object.md | 4 -- src/coreclr/debug/runtimeinfo/contracts.jsonc | 3 +- .../ContractRegistry.cs | 4 ++ .../Contracts/IComWrappers.cs | 17 ++++++ .../Contracts/ComWrappersFactory.cs | 18 +++++++ .../Contracts/ComWrappers_1.cs | 25 +++++++++ .../Contracts/Object_1.cs | 10 ---- .../CachingContractRegistry.cs | 2 + .../ContractDescriptorTarget.cs | 10 +++- .../Legacy/ClrDataModule.cs | 2 +- .../Legacy/ISOSDacInterface.cs | 5 ++ .../Legacy/SOSDacImpl.cs | 6 ++- 13 files changed, 141 insertions(+), 19 deletions(-) create mode 100644 docs/design/datacontracts/ComWrappers.md create mode 100644 src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IComWrappers.cs create mode 100644 src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappersFactory.cs create mode 100644 src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappers_1.cs diff --git a/docs/design/datacontracts/ComWrappers.md b/docs/design/datacontracts/ComWrappers.md new file mode 100644 index 00000000000000..0ac6a25bbabcc1 --- /dev/null +++ b/docs/design/datacontracts/ComWrappers.md @@ -0,0 +1,54 @@ +# Contract ComWrappers + +This contract is for getting information related to COM wrappers. + +## APIs of contract + +``` csharp +// Get the address of the external COM object +TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw); +``` + +## Version 1 + +Data descriptors used: +| Data Descriptor Name | Field | Meaning | +| --- | --- | --- | +| `Array` | `m_NumComponents` | Number of items in the array | +| `InteropSyncBlockInfo` | `RCW` | Pointer to the RCW for the object (if it exists) | +| `InteropSyncBlockInfo` | `CCW` | Pointer to the CCW for the object (if it exists) | +| `Object` | `m_pMethTab` | Method table for the object | +| `String` | `m_FirstChar` | First character of the string - `m_StringLength` can be used to read the full string (encoded in UTF-16) | +| `String` | `m_StringLength` | Length of the string in characters (encoded in UTF-16) | +| `SyncBlock` | `InteropInfo` | Optional `InteropSyncBlockInfo` for the sync block | +| `SyncTableEntry` | `SyncBlock` | `SyncBlock` corresponding to the entry | +| `NativeObjectWrapperObject` | `ExternalComObject` | Address of the external COM object | + +Global variables used: +| Global Name | Type | Purpose | +| --- | --- | --- | +| `ArrayBoundsZero` | TargetPointer | Known value for single dimensional, zero-lower-bound array | +| `ObjectHeaderSize` | uint32 | Size of the object header (sync block and alignment) | +| `ObjectToMethodTableUnmask` | uint8 | Bits to clear for converting to a method table address | +| `StringMethodTable` | TargetPointer | The method table for System.String | +| `SyncTableEntries` | TargetPointer | The `SyncTableEntry` list | +| `SyncBlockValueToObjectOffset` | uint16 | Offset from the sync block value (in the object header) to the object itself | + +Contracts used: +| Contract Name | +| --- | +| `RuntimeTypeSystem` | + +``` csharp +string StringFromEEAddress(TargetPointer address) +{ + TargetPointer miniMetaDataBuffAddress = _target.Read(_target.ReadGlobalPointer(Constants.Globals.MiniMetaDataBuffAddress)); + uint miniMetaDataBuffMaxSize = _target.Read(_target.ReadGlobalPointer(Constants.Globals.MiniMetaDataBuffMaxSize)); + + // Parse MiniMetadataStream according the the format described above to produce a dictionary from pointer to string from the EENameStream. + // Then lookup in the dictionary, to produce a result if it was present in the table. + // In general, since this api is intended for fallback scenarios, implementations of this api should attempt + // to return null instead of producing errors. + // Since in normal execution of the runtime no stream is constructed, it is normal when examining full dumps and live process state without a stream encoded. +} +``` diff --git a/docs/design/datacontracts/Object.md b/docs/design/datacontracts/Object.md index a964f7d56d7ef6..18b6d0c9befe18 100644 --- a/docs/design/datacontracts/Object.md +++ b/docs/design/datacontracts/Object.md @@ -16,9 +16,6 @@ TargetPointer GetArrayData(TargetPointer address, out uint count, out TargetPoin // Get built-in COM data for the object if available. Returns false, if address does not represent a COM object using built-in COM bool GetBuiltInComData(TargetPointer address, out TargetPointer rcw, out TargetPointer ccw); - -// Get the address of the external COM object -TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw); ``` ## Version 1 @@ -34,7 +31,6 @@ Data descriptors used: | `String` | `m_StringLength` | Length of the string in characters (encoded in UTF-16) | | `SyncBlock` | `InteropInfo` | Optional `InteropSyncBlockInfo` for the sync block | | `SyncTableEntry` | `SyncBlock` | `SyncBlock` corresponding to the entry | -| `NativeObjectWrapperObject` | `ExternalComObject` | Address of the external COM object | Global variables used: | Global Name | Type | Purpose | diff --git a/src/coreclr/debug/runtimeinfo/contracts.jsonc b/src/coreclr/debug/runtimeinfo/contracts.jsonc index 81b28cd2e1fe92..9ad3378d54b020 100644 --- a/src/coreclr/debug/runtimeinfo/contracts.jsonc +++ b/src/coreclr/debug/runtimeinfo/contracts.jsonc @@ -23,5 +23,6 @@ "RuntimeTypeSystem": 1, "StackWalk": 1, "StressLog": 2, - "Thread": 1 + "Thread": 1, + "ComWrappers": 1 } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/ContractRegistry.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/ContractRegistry.cs index 53faad2d53f99b..5afbcd4d536fef 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/ContractRegistry.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/ContractRegistry.cs @@ -67,4 +67,8 @@ public abstract class ContractRegistry /// Gets an instance of the RuntimeInfo contract for the target. /// public abstract IRuntimeInfo RuntimeInfo { get; } + /// + /// Gets an instance of the ComWrappers contract for the target. + /// + public abstract IComWrappers ComWrappers { get; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IComWrappers.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IComWrappers.cs new file mode 100644 index 00000000000000..350634bea81fe6 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IComWrappers.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Contracts; + +public interface IComWrappers : IContract +{ + static string IContract.Name { get; } = nameof(ComWrappers); + TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw) => throw new NotImplementedException(); +} + +public readonly struct ComWrappers : IComWrappers +{ + // Everything throws NotImplementedException +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappersFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappersFactory.cs new file mode 100644 index 00000000000000..c5de208863b0df --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappersFactory.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Contracts; + +public sealed class ComWrappersFactory : IContractFactory +{ + IComWrappers IContractFactory.CreateContract(Target target, int version) + { + return version switch + { + 1 => new ComWrappers_1(target), + _ => default(ComWrappers), + }; + } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappers_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappers_1.cs new file mode 100644 index 00000000000000..ba51cc174711f7 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappers_1.cs @@ -0,0 +1,25 @@ +// 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.Collections.Generic; +using System.Diagnostics; +using Microsoft.Diagnostics.DataContractReader.Data; + +namespace Microsoft.Diagnostics.DataContractReader.Contracts; + +internal readonly partial struct ComWrappers_1 : IComWrappers +{ + private readonly Target _target; + + public ComWrappers_1(Target target) + { + _target = target; + } + + public TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw) + { + Data.NativeObjectWrapperObject wrapper = _target.ProcessedData.GetOrAdd(rcw); + return wrapper.ExternalComObject; + } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs index 02b89046cd4658..d35b683f028fb1 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs @@ -129,14 +129,4 @@ public bool GetBuiltInComData(TargetPointer address, out TargetPointer rcw, out Data.SyncTableEntry entry = _target.ProcessedData.GetOrAdd(_syncTableEntries + offsetInSyncTableEntries); return entry.SyncBlock; } - - public TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw) - { - if ((rcw.Value & 1) == 0) - { - return TargetPointer.Null; // Invalid RCW address - } - Data.NativeObjectWrapperObject wrapper = _target.ProcessedData.GetOrAdd(rcw.Value & ~1UL); - return wrapper.ExternalComObject; - } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs index 7b339281951cbe..3a333c75548add 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs @@ -39,6 +39,7 @@ public CachingContractRegistry(Target target, TryGetContractVersionDelegate tryG [typeof(IReJIT)] = new ReJITFactory(), [typeof(IStackWalk)] = new StackWalkFactory(), [typeof(IRuntimeInfo)] = new RuntimeInfoFactory(), + [typeof(IComWrappers)] = new ComWrappersFactory(), }; configureFactories?.Invoke(_factories); } @@ -57,6 +58,7 @@ public CachingContractRegistry(Target target, TryGetContractVersionDelegate tryG public override IReJIT ReJIT => GetContract(); public override IStackWalk StackWalk => GetContract(); public override IRuntimeInfo RuntimeInfo => GetContract(); + public override IComWrappers ComWrappers => GetContract(); private TContract GetContract() where TContract : IContract { diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs index f73f955a128e46..449ab71d84610b 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs @@ -646,7 +646,15 @@ public Target.TypeInfo GetTypeInfo(string type) } internal bool TryGetContractVersion(string contractName, out int version) - => _contracts.TryGetValue(contractName, out version); + { + foreach (var kvp in _contracts) + { + var name = kvp.Key; + var value = kvp.Value; + Console.WriteLine($"Contract: {name}, Version: {value}"); + } + return _contracts.TryGetValue(contractName, out version); + } /// /// Store of addresses that have already been read into corresponding data models. diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataModule.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataModule.cs index 56eca6885f0170..aa90aba8091cd8 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataModule.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataModule.cs @@ -36,7 +36,7 @@ public ClrDataModule(TargetPointer address, Target target, IXCLRDataModule? lega _target = target; _legacyModule = legacyImpl; _legacyModule2 = legacyImpl as IXCLRDataModule2; - if (legacyImpl is not null && ComWrappers.TryGetComInstance(legacyImpl, out _legacyModulePointer)) + if (legacyImpl is not null && System.Runtime.InteropServices.ComWrappers.TryGetComInstance(legacyImpl, out _legacyModulePointer)) { // Release the AddRef from TryGetComInstance. We rely on the ref-count from holding on to IXCLRDataModule. Marshal.Release(_legacyModulePointer); diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/ISOSDacInterface.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/ISOSDacInterface.cs index 3d3e2774d22db5..471b497e4c98a1 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/ISOSDacInterface.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/ISOSDacInterface.cs @@ -12,6 +12,11 @@ namespace Microsoft.Diagnostics.DataContractReader.Legacy; #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value +internal struct ComWrappersConstants +{ + public const ulong rcwMask = 1UL; +} + internal enum CLRDataOtherNotifyFlag { CLRDATA_NOTIFY_ON_MODULE_LOAD = 0x1, diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs index e60103aaa87ed5..70553f498660f4 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs @@ -2377,14 +2377,16 @@ int ISOSDacInterface10.GetComWrappersRCWData(ClrDataAddress rcw, ClrDataAddress* hr = HResults.E_NOTIMPL; else if (rcw == 0) hr = HResults.E_INVALIDARG; + else if ((rcw & ComWrappersConstants.rcwMask) == 0) + *identity = 0; else { try { if (identity != null) { - Contracts.IObject objectContract = _target.Contracts.Object; - TargetPointer identityPtr = objectContract.GetComWrappersRCWIdentity(rcw.ToTargetPointer(_target)); + Contracts.IComWrappers comWrappersContract = _target.Contracts.ComWrappers; + TargetPointer identityPtr = comWrappersContract.GetComWrappersRCWIdentity((rcw.ToTargetPointer(_target) & ~(ComWrappersConstants.rcwMask))); *identity = identityPtr.ToClrDataAddress(_target); } } From 85d3742d972ba375433fbb85e2d3c72b41073a3f Mon Sep 17 00:00:00 2001 From: rcj1 Date: Wed, 10 Sep 2025 09:51:39 -0700 Subject: [PATCH 3/7] adding GetComWrappersRCWData cDAC API --- docs/design/datacontracts/ComWrappers.md | 29 ++---------- src/coreclr/clrdatadescriptors.cmake | 7 ++- .../datadescriptor-shared/datadescriptor.cpp | 27 ++++++++++++ .../wrappeddatadescriptor.inc | 4 ++ src/coreclr/gc/datadescriptor/CMakeLists.txt | 4 -- src/coreclr/gc/datadescriptor/contracts.jsonc | 13 ------ .../gc/datadescriptor/datadescriptor.inc | 2 + .../tools/cdac-build-tool/ComposeCommand.cs | 15 ------- .../tools/cdac-build-tool/ContractReader.cs | 33 -------------- .../cdac-build-tool/DataDescriptorModel.cs | 8 ---- .../cdac-build-tool/ObjectFileScraper.cs | 44 ++++++++++++++++++- src/coreclr/vm/datadescriptor/CMakeLists.txt | 3 -- src/coreclr/vm/datadescriptor/contracts.jsonc | 28 ------------ .../vm/datadescriptor/datadescriptor.h | 1 + .../vm/datadescriptor/datadescriptor.inc | 26 ++++++++++- .../Contracts/IComWrappers.cs | 2 +- .../Contracts/IObject.cs | 1 - .../Constants.cs | 4 +- .../Contracts/ComWrappers_1.cs | 4 +- .../Contracts/PlatformMetadataFactory.cs | 2 +- .../Contracts/StressLog.cs | 6 +-- .../Legacy/SOSDacImpl.cs | 42 ++++++++++-------- .../managed/cdac/tests/PrecodeStubsTests.cs | 2 +- 23 files changed, 141 insertions(+), 166 deletions(-) delete mode 100644 src/coreclr/gc/datadescriptor/contracts.jsonc delete mode 100644 src/coreclr/tools/cdac-build-tool/ContractReader.cs delete mode 100644 src/coreclr/vm/datadescriptor/contracts.jsonc diff --git a/docs/design/datacontracts/ComWrappers.md b/docs/design/datacontracts/ComWrappers.md index 0ac6a25bbabcc1..73c3bcd9930728 100644 --- a/docs/design/datacontracts/ComWrappers.md +++ b/docs/design/datacontracts/ComWrappers.md @@ -6,7 +6,7 @@ This contract is for getting information related to COM wrappers. ``` csharp // Get the address of the external COM object -TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw); +TargetPointer GetComWrappersIdentity(TargetPointer rcw); ``` ## Version 1 @@ -14,41 +14,20 @@ TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw); Data descriptors used: | Data Descriptor Name | Field | Meaning | | --- | --- | --- | -| `Array` | `m_NumComponents` | Number of items in the array | -| `InteropSyncBlockInfo` | `RCW` | Pointer to the RCW for the object (if it exists) | -| `InteropSyncBlockInfo` | `CCW` | Pointer to the CCW for the object (if it exists) | -| `Object` | `m_pMethTab` | Method table for the object | -| `String` | `m_FirstChar` | First character of the string - `m_StringLength` can be used to read the full string (encoded in UTF-16) | -| `String` | `m_StringLength` | Length of the string in characters (encoded in UTF-16) | -| `SyncBlock` | `InteropInfo` | Optional `InteropSyncBlockInfo` for the sync block | -| `SyncTableEntry` | `SyncBlock` | `SyncBlock` corresponding to the entry | | `NativeObjectWrapperObject` | `ExternalComObject` | Address of the external COM object | Global variables used: | Global Name | Type | Purpose | | --- | --- | --- | -| `ArrayBoundsZero` | TargetPointer | Known value for single dimensional, zero-lower-bound array | -| `ObjectHeaderSize` | uint32 | Size of the object header (sync block and alignment) | -| `ObjectToMethodTableUnmask` | uint8 | Bits to clear for converting to a method table address | -| `StringMethodTable` | TargetPointer | The method table for System.String | -| `SyncTableEntries` | TargetPointer | The `SyncTableEntry` list | -| `SyncBlockValueToObjectOffset` | uint16 | Offset from the sync block value (in the object header) to the object itself | Contracts used: | Contract Name | | --- | -| `RuntimeTypeSystem` | + ``` csharp -string StringFromEEAddress(TargetPointer address) +public TargetPointer GetComWrappersIdentity(TargetPointer address) { - TargetPointer miniMetaDataBuffAddress = _target.Read(_target.ReadGlobalPointer(Constants.Globals.MiniMetaDataBuffAddress)); - uint miniMetaDataBuffMaxSize = _target.Read(_target.ReadGlobalPointer(Constants.Globals.MiniMetaDataBuffMaxSize)); - - // Parse MiniMetadataStream according the the format described above to produce a dictionary from pointer to string from the EENameStream. - // Then lookup in the dictionary, to produce a result if it was present in the table. - // In general, since this api is intended for fallback scenarios, implementations of this api should attempt - // to return null instead of producing errors. - // Since in normal execution of the runtime no stream is constructed, it is normal when examining full dumps and live process state without a stream encoded. + return _target.ReadPointer(address + /* NativeObjectWrapperObject::ExternalComObject offset */); } ``` diff --git a/src/coreclr/clrdatadescriptors.cmake b/src/coreclr/clrdatadescriptors.cmake index bd3d13836b4f08..01f9b702350954 100644 --- a/src/coreclr/clrdatadescriptors.cmake +++ b/src/coreclr/clrdatadescriptors.cmake @@ -2,7 +2,7 @@ function(generate_data_descriptors) set(options EXPORT_VISIBLE) - set(oneValueArgs LIBRARY_NAME CONTRACT_FILE CONTRACT_NAME INTERFACE_TARGET) + set(oneValueArgs LIBRARY_NAME CONTRACT_NAME INTERFACE_TARGET) set(multiValueArgs "") cmake_parse_arguments(DATA_DESCRIPTORS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV}) @@ -53,15 +53,14 @@ function(generate_data_descriptors) set(CONTRACT_BASELINE_DIR "${CLR_REPO_ROOT_DIR}/docs/design/datacontracts/data") set(CONTRACT_DESCRIPTOR_INPUT "${DATA_DESCRIPTOR_SHARED_SOURCE_DIR}/contract-descriptor.c.in") set(CONTRACT_DESCRIPTOR_OUTPUT "${GENERATED_CDAC_DESCRIPTOR_DIR}/contract-descriptor.c") - set(CONTRACT_FILE "${DATA_DESCRIPTORS_CONTRACT_FILE}") # generate the contract descriptor by running cdac-build-tool # n.b. this just uses `dotnet` from the PATH. InitializeDotNetCli adds the appropriate directory add_custom_command( OUTPUT "${CONTRACT_DESCRIPTOR_OUTPUT}" VERBATIM - COMMAND ${CLR_DOTNET_HOST_PATH} ${CDAC_BUILD_TOOL_BINARY_PATH} compose -i "${CONTRACT_DESCRIPTOR_INPUT}" -o "${CONTRACT_DESCRIPTOR_OUTPUT}" -b "${CONTRACT_BASELINE_DIR}" -c "${CONTRACT_FILE}" $ - DEPENDS ${INTERMEDIARY_LIBRARY} ${DATA_DESCRIPTORS_DEPENDENCIES} $ "${CONTRACT_FILE}" "${CONTRACT_DESCRIPTOR_INPUT}" + COMMAND ${CLR_DOTNET_HOST_PATH} ${CDAC_BUILD_TOOL_BINARY_PATH} compose -i "${CONTRACT_DESCRIPTOR_INPUT}" -o "${CONTRACT_DESCRIPTOR_OUTPUT}" -b "${CONTRACT_BASELINE_DIR}" $ + DEPENDS ${INTERMEDIARY_LIBRARY} ${DATA_DESCRIPTORS_DEPENDENCIES} $ "${CONTRACT_DESCRIPTOR_INPUT}" USES_TERMINAL ) diff --git a/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp b/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp index e7d3a01c6a6a96..4206f89277bb1c 100644 --- a/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp +++ b/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp @@ -49,6 +49,12 @@ struct GlobalStringSpec uint32_t StringValue; }; +struct GlobalContractSpec +{ + uint32_t Name; + uint32_t Version; +}; + #define CONCAT(token1,token2) token1 ## token2 #define CONCAT4(token1, token2, token3, token4) token1 ## token2 ## token3 ## token4 @@ -78,6 +84,7 @@ struct CDacStringPoolSizes DECL_LEN(MAKE_GLOBALVALUELEN_NAME(name), sizeof(STRINGIFY(stringval))) #define CDAC_GLOBAL_POINTER(name,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) #define CDAC_GLOBAL_SUB_DESCRIPTOR(name,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) +#define CDAC_GLOBAL_CONTRACT(name,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) #define CDAC_GLOBAL(name,tyname,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) \ DECL_LEN(MAKE_GLOBALTYPELEN_NAME(name), sizeof(#tyname)) #include "wrappeddatadescriptor.inc" @@ -148,6 +155,15 @@ enum #include "wrappeddatadescriptor.inc" }; +// count the contracts +enum +{ + CDacBlobGlobalContractsCount = +#define CDAC_GLOBALS_BEGIN() 0 +#define CDAC_GLOBAL_CONTRACT(name,value) + 1 +#include "wrappeddatadescriptor.inc" +}; + #define MAKE_TYPEFIELDS_TYNAME(tyname) CONCAT(CDacFieldsPoolTypeStart__, tyname) @@ -226,6 +242,7 @@ struct BinaryBlobDataDescriptor uint32_t GlobalStringValuesStart; uint32_t GlobalSubDescriptorsStart; + uint32_t ContractsStart; uint32_t NamesPoolStart; uint32_t TypeCount; @@ -235,6 +252,7 @@ struct BinaryBlobDataDescriptor uint32_t GlobalPointerValuesCount; uint32_t GlobalStringValuesCount; uint32_t GlobalSubDescriptorsCount; + uint32_t GlobalContractsCount; uint32_t NamesPoolCount; @@ -253,6 +271,7 @@ struct BinaryBlobDataDescriptor struct GlobalPointerSpec GlobalPointerValues[CDacBlobGlobalPointersCount + 1]; struct GlobalStringSpec GlobalStringValues[CDacBlobGlobalStringsCount + 1]; struct GlobalPointerSpec GlobalSubDescriptorValues[CDacBlobGlobalSubDescriptorsCount + 1]; + struct GlobalContractSpec GlobalContractValues[CDacBlobGlobalContractsCount + 1]; uint8_t NamesPool[sizeof(struct CDacStringPoolSizes)]; uint8_t EndMagic[4]; }; @@ -279,6 +298,7 @@ struct MagicAndBlob BlobDataDescriptor = { /* .GlobalPointersStart = */ offsetof(struct BinaryBlobDataDescriptor, GlobalPointerValues), /* .GlobalStringValuesStart = */ offsetof(struct BinaryBlobDataDescriptor, GlobalStringValues), /* .GlobalSubDescriptorsStart = */ offsetof(struct BinaryBlobDataDescriptor, GlobalSubDescriptorValues), + /* .ContractsStart = */ offsetof(struct BinaryBlobDataDescriptor, GlobalContractValues), /* .NamesPoolStart = */ offsetof(struct BinaryBlobDataDescriptor, NamesPool), /* .TypeCount = */ CDacBlobTypesCount, /* .FieldsPoolCount = */ CDacBlobFieldsPoolCount, @@ -286,6 +306,7 @@ struct MagicAndBlob BlobDataDescriptor = { /* .GlobalPointerValuesCount = */ CDacBlobGlobalPointersCount, /* .GlobalStringValuesCount = */ CDacBlobGlobalStringsCount, /* .GlobalSubDescriptorsCount = */ CDacBlobGlobalSubDescriptorsCount, + /* .GlobalContractsCount = */ CDacBlobGlobalContractsCount, /* .NamesPoolCount = */ sizeof(struct CDacStringPoolSizes), /* .TypeSpecSize = */ sizeof(struct TypeSpec), /* .FieldSpecSize = */ sizeof(struct FieldSpec), @@ -337,6 +358,11 @@ struct MagicAndBlob BlobDataDescriptor = { #include "wrappeddatadescriptor.inc" }, + /* .GlobalContractValues = */ { +#define CDAC_GLOBAL_CONTRACT(name,value) { /* .Name = */ GET_GLOBAL_NAME(name), /* .Version = */ value }, +#include "wrappeddatadescriptor.inc" + }, + /* .NamesPool = */ ("\0" // starts with a nul #define CDAC_BASELINE(name) name "\0" #define CDAC_TYPE_BEGIN(name) #name "\0" @@ -344,6 +370,7 @@ struct MagicAndBlob BlobDataDescriptor = { #define CDAC_GLOBAL_STRING(name,value) #name "\0" STRINGIFY(value) "\0" #define CDAC_GLOBAL_POINTER(name,value) #name "\0" #define CDAC_GLOBAL_SUB_DESCRIPTOR(name,value) #name "\0" +#define CDAC_GLOBAL_CONTRACT(name,value) #name "\0" #define CDAC_GLOBAL(name,tyname,value) #name "\0" #tyname "\0" #include "wrappeddatadescriptor.inc" ), diff --git a/src/coreclr/debug/datadescriptor-shared/wrappeddatadescriptor.inc b/src/coreclr/debug/datadescriptor-shared/wrappeddatadescriptor.inc index abb73293885cb9..8c668e6869c158 100644 --- a/src/coreclr/debug/datadescriptor-shared/wrappeddatadescriptor.inc +++ b/src/coreclr/debug/datadescriptor-shared/wrappeddatadescriptor.inc @@ -43,6 +43,9 @@ #ifndef CDAC_GLOBAL_SUB_DESCRIPTOR #define CDAC_GLOBAL_SUB_DESCRIPTOR(globalname,addr) #endif +#ifndef CDAC_GLOBAL_CONTRACT +#define CDAC_GLOBAL_CONTRACT(name,value) +#endif #ifndef CDAC_GLOBALS_END #define CDAC_GLOBALS_END() #endif @@ -62,4 +65,5 @@ #undef CDAC_GLOBAL_POINTER #undef CDAC_GLOBAL_STRING #undef CDAC_GLOBAL_SUB_DESCRIPTOR +#undef CDAC_GLOBAL_CONTRACT #undef CDAC_GLOBALS_END diff --git a/src/coreclr/gc/datadescriptor/CMakeLists.txt b/src/coreclr/gc/datadescriptor/CMakeLists.txt index 786969587fef6e..0b629cd05d1865 100644 --- a/src/coreclr/gc/datadescriptor/CMakeLists.txt +++ b/src/coreclr/gc/datadescriptor/CMakeLists.txt @@ -13,7 +13,6 @@ add_dependencies(gc_dll_wks_descriptor_interface eventing_headers) generate_data_descriptors( LIBRARY_NAME gc_dll_wks_descriptor CONTRACT_NAME "GCContractDescriptorWKS" - CONTRACT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/contracts.jsonc" INTERFACE_TARGET gc_dll_wks_descriptor_interface) if (FEATURE_SVR_GC) @@ -25,7 +24,6 @@ if (FEATURE_SVR_GC) generate_data_descriptors( LIBRARY_NAME gc_dll_svr_descriptor CONTRACT_NAME "GCContractDescriptorSVR" - CONTRACT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/contracts.jsonc" INTERFACE_TARGET gc_dll_svr_descriptor_interface) endif() @@ -38,7 +36,6 @@ if(BUILD_EXP_GC) generate_data_descriptors( LIBRARY_NAME gcexp_dll_wks_descriptor CONTRACT_NAME "GCContractDescriptorWKS" - CONTRACT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/contracts.jsonc" INTERFACE_TARGET gcexp_dll_wks_descriptor_interface) if (FEATURE_SVR_GC) @@ -51,7 +48,6 @@ if(BUILD_EXP_GC) generate_data_descriptors( LIBRARY_NAME gcexp_dll_svr_descriptor CONTRACT_NAME "GCContractDescriptorSVR" - CONTRACT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/contracts.jsonc" INTERFACE_TARGET gcexp_dll_svr_descriptor_interface) endif() endif() diff --git a/src/coreclr/gc/datadescriptor/contracts.jsonc b/src/coreclr/gc/datadescriptor/contracts.jsonc deleted file mode 100644 index 99ece99f677fa1..00000000000000 --- a/src/coreclr/gc/datadescriptor/contracts.jsonc +++ /dev/null @@ -1,13 +0,0 @@ -//algorithmic contracts for coreclr -// The format of this file is: JSON with comments -// { -// "CONTRACT NAME": VERSION, -// ... -// } -// CONTRACT NAME is an arbitrary string, VERSION is an integer -// -// cdac-build-tool can take multiple "-c contract_file" arguments -// so to conditionally include contracts, put additional contracts in a separate file -{ - "GC": 1 -} diff --git a/src/coreclr/gc/datadescriptor/datadescriptor.inc b/src/coreclr/gc/datadescriptor/datadescriptor.inc index 343182ef0822af..ac20f6cc00fc60 100644 --- a/src/coreclr/gc/datadescriptor/datadescriptor.inc +++ b/src/coreclr/gc/datadescriptor/datadescriptor.inc @@ -100,4 +100,6 @@ CDAC_GLOBAL_POINTER(Heaps, cdac_data::Heaps) CDAC_GLOBAL_POINTER(CurrentGCState, cdac_data::CurrentGCState) #endif // BACKGROUND_GC +CDAC_GLOBAL_CONTRACT(GC, 1) + CDAC_GLOBALS_END() diff --git a/src/coreclr/tools/cdac-build-tool/ComposeCommand.cs b/src/coreclr/tools/cdac-build-tool/ComposeCommand.cs index 36b1576dd0a5d5..8defe8708dcf38 100644 --- a/src/coreclr/tools/cdac-build-tool/ComposeCommand.cs +++ b/src/coreclr/tools/cdac-build-tool/ComposeCommand.cs @@ -12,7 +12,6 @@ internal sealed class ComposeCommand : Command { private readonly Argument inputFiles = new("INPUT [INPUTS...]") { Arity = ArgumentArity.OneOrMore, Description = "One or more input files" }; private readonly Option outputFile = new("-o") { Arity = ArgumentArity.ExactlyOne, HelpName = "OUTPUT", Required = true, Description = "Output file" }; - private readonly Option contractFile = new("-c") { Arity = ArgumentArity.ZeroOrMore, HelpName = "CONTRACT", Description = "Contract file (may be specified multiple times)" }; private readonly Option baselinePath = new("-b", "--baseline") { Arity = ArgumentArity.ExactlyOne, HelpName = "BASELINEPATH", Description = "Directory containing the baseline contracts"}; private readonly Option templateFile = new("-i", "--input-template") { Arity = ArgumentArity.ExactlyOne, HelpName = "TEMPLATE", Description = "Contract descriptor template to be filled in" }; private readonly Option _verboseOption; @@ -21,7 +20,6 @@ public ComposeCommand(Option verboseOption) : base("compose") _verboseOption = verboseOption; Add(inputFiles); Add(outputFile); - Add(contractFile); Add(baselinePath); Add(templateFile); SetAction(Run); @@ -65,7 +63,6 @@ private async Task Run(ParseResult parse, CancellationToken token = default Console.Error.WriteLine($"Template file {templateFilePath} does not exist"); return 1; } - var contracts = parse.GetValue(contractFile); var verbose = parse.GetValue(_verboseOption); var builder = new DataDescriptorModel.Builder(baselinesDir); var scraper = new ObjectFileScraper(verbose, builder); @@ -78,18 +75,6 @@ private async Task Run(ParseResult parse, CancellationToken token = default return 1; } } - if (contracts != null) - { - var contractReader = new ContractReader(builder); - foreach (var contract in contracts) - { - if (!await contractReader.ParseContracts(contract, token).ConfigureAwait(false)) - { - Console.Error.WriteLine($"could not parse contracts in {contract}"); - return 1; - } - } - } var model = builder.Build(); if (verbose) diff --git a/src/coreclr/tools/cdac-build-tool/ContractReader.cs b/src/coreclr/tools/cdac-build-tool/ContractReader.cs deleted file mode 100644 index 3bd8ec0c77e7f5..00000000000000 --- a/src/coreclr/tools/cdac-build-tool/ContractReader.cs +++ /dev/null @@ -1,33 +0,0 @@ -// 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.Collections.Generic; -using System.IO; -using System.Text.Json; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.DotNet.Diagnostics.DataContract.BuildTool; - -public class ContractReader -{ - private readonly DataDescriptorModel.Builder _builder; - - private static readonly JsonSerializerOptions s_jsonSerializerOptions = new() { PropertyNameCaseInsensitive = false, ReadCommentHandling = JsonCommentHandling.Skip }; - - public ContractReader(DataDescriptorModel.Builder builder) - { - _builder = builder; - } - - public async Task ParseContracts(string contractFilePath, CancellationToken token = default) - { - string? contents = await File.ReadAllTextAsync(contractFilePath, token).ConfigureAwait(false); - var contracts = JsonSerializer.Deserialize>(contents, s_jsonSerializerOptions); - if (contracts is null) - return false; - _builder.AddOrupdateContracts(contracts); - return true; - } -} diff --git a/src/coreclr/tools/cdac-build-tool/DataDescriptorModel.cs b/src/coreclr/tools/cdac-build-tool/DataDescriptorModel.cs index 730185a4efd6ca..65bff7fa48861e 100644 --- a/src/coreclr/tools/cdac-build-tool/DataDescriptorModel.cs +++ b/src/coreclr/tools/cdac-build-tool/DataDescriptorModel.cs @@ -165,14 +165,6 @@ public void AddOrUpdateContract(string name, int version) contract.Version = version; } - public void AddOrupdateContracts(IEnumerable> contracts) - { - foreach (var (name, version) in contracts) - { - AddOrUpdateContract(name, version); - } - } - public void SetBaseline(string baseline) { if (_baseline != string.Empty && _baseline != baseline) diff --git a/src/coreclr/tools/cdac-build-tool/ObjectFileScraper.cs b/src/coreclr/tools/cdac-build-tool/ObjectFileScraper.cs index 59f492e5a97253..a8481e22f8541d 100644 --- a/src/coreclr/tools/cdac-build-tool/ObjectFileScraper.cs +++ b/src/coreclr/tools/cdac-build-tool/ObjectFileScraper.cs @@ -163,6 +163,7 @@ private struct HeaderDirectory public uint GlobalStringValuesStart; public uint GlobalSubDescriptorsStart; + public uint ContractsStart; public uint NamesStart; public uint TypesCount; @@ -172,6 +173,7 @@ private struct HeaderDirectory public uint GlobalPointerValuesCount; public uint GlobalStringValuesCount; public uint GlobalSubDescriptorsCount; + public uint GlobalContractsCount; public uint NamesPoolCount; @@ -220,6 +222,7 @@ private static HeaderDirectory ReadHeader(ScraperState state) var globalStringValuesStart = state.ReadUInt32(); var globalSubDescriptorsStart = state.ReadUInt32(); + var contractsStart = state.ReadUInt32(); var namesStart = state.ReadUInt32(); var typeCount = state.ReadUInt32(); @@ -230,6 +233,7 @@ private static HeaderDirectory ReadHeader(ScraperState state) var globalStringValuesCount = state.ReadUInt32(); var globalSubDescriptorsCount = state.ReadUInt32(); + var globalContractsCount = state.ReadUInt32(); var namesPoolCount = state.ReadUInt32(); @@ -247,6 +251,7 @@ private static HeaderDirectory ReadHeader(ScraperState state) GlobalPointersStart = globalPointersStart, GlobalStringValuesStart = globalStringValuesStart, GlobalSubDescriptorsStart = globalSubDescriptorsStart, + ContractsStart = contractsStart, NamesStart = namesStart, TypesCount = typeCount, @@ -257,6 +262,7 @@ private static HeaderDirectory ReadHeader(ScraperState state) GlobalStringValuesCount = globalStringValuesCount, GlobalSubDescriptorsCount = globalSubDescriptorsCount, + GlobalContractsCount = globalContractsCount, NamesPoolCount = namesPoolCount, @@ -309,9 +315,15 @@ private struct GlobalStringSpec public uint ValueIdx; } + private struct GlobalContractSpec + { + public uint NameIdx; + public uint Value; + } + private sealed class Content { - public required bool Verbose {get; init; } + public required bool Verbose { get; init; } public required uint PlatformFlags { get; init; } public required uint Baseline { get; init; } public required IReadOnlyList TypeSpecs { get; init; } @@ -320,6 +332,7 @@ private sealed class Content public required IReadOnlyList GlobalPointerSpecs { get; init; } public required IReadOnlyList GlobalStringSpecs { get; init; } public required IReadOnlyList GlobalSubDescriptorSpecs { get; init; } + public required IReadOnlyList GlobalContractSpecs { get; init; } public required ReadOnlyMemory NamesPool { get; init; } internal string GetPoolString(uint stringIdx) @@ -408,6 +421,14 @@ public void AddToModel(DataDescriptorModel.Builder builder) builder.AddOrUpdateSubDescriptor(globalName, DataDescriptorModel.PointerTypeName, globalValue); WriteVerbose($"Global sub-descriptor {globalName} has index {globalValue}"); } + + foreach (var contract in GlobalContractSpecs) + { + var globalName = GetPoolString(contract.NameIdx); + var value = contract.Value; + builder.AddOrUpdateContract(globalName, (int)value); + WriteVerbose($"Contract {globalName} has value {value}"); + } } private void WriteVerbose(string msg) @@ -431,6 +452,7 @@ private Content ReadContent(ScraperState state, HeaderDirectory header) GlobalPointerSpec[] globalPointerSpecs = ReadGlobalPointerSpecs(state, header); GlobalStringSpec[] globalStringSpecs = ReadGlobalStringSpecs(state, header); GlobalPointerSpec[] globalSubDescriptorSpecs = ReadGlobalSubDescriptorSpecs(state, header); + GlobalContractSpec[] globalContractSpecs = ReadGlobalContractSpecs(state, header); byte[] namesPool = ReadNamesPool(state, header); byte[] endMagic = new byte[4]; @@ -458,6 +480,7 @@ private Content ReadContent(ScraperState state, HeaderDirectory header) GlobalPointerSpecs = globalPointerSpecs, GlobalStringSpecs = globalStringSpecs, GlobalSubDescriptorSpecs = globalSubDescriptorSpecs, + GlobalContractSpecs = globalContractSpecs, NamesPool = namesPool }; } @@ -594,6 +617,25 @@ private static GlobalPointerSpec[] ReadGlobalSubDescriptorSpecs(ScraperState sta return globalSpecs; } + private static GlobalContractSpec[] ReadGlobalContractSpecs(ScraperState state, HeaderDirectory header) + { + GlobalContractSpec[] globalSpecs = new GlobalContractSpec[header.GlobalContractsCount]; + state.ResetPosition(state.HeaderStart + (long)header.ContractsStart); + for (int i = 0; i < header.GlobalContractsCount; i++) + { + int bytesRead = 0; + globalSpecs[i].NameIdx = state.ReadUInt32(); + bytesRead += sizeof(uint); + globalSpecs[i].Value = state.ReadUInt32(); + bytesRead += sizeof(uint); + // skip padding + if (bytesRead < header.GlobalPointerSpecSize) + { + state.Skip(header.GlobalPointerSpecSize - bytesRead); + } + } + return globalSpecs; + } private static byte[] ReadNamesPool(ScraperState state, HeaderDirectory header) { byte[] namesPool = new byte[header.NamesPoolCount]; diff --git a/src/coreclr/vm/datadescriptor/CMakeLists.txt b/src/coreclr/vm/datadescriptor/CMakeLists.txt index c7eab6d807c10d..dabe48a83d6fb7 100644 --- a/src/coreclr/vm/datadescriptor/CMakeLists.txt +++ b/src/coreclr/vm/datadescriptor/CMakeLists.txt @@ -14,7 +14,6 @@ target_include_directories(runtime_descriptor_interface INTERFACE add_dependencies(runtime_descriptor_interface cee_wks_core) generate_data_descriptors( LIBRARY_NAME cdac_contract_descriptor - CONTRACT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/contracts.jsonc" CONTRACT_NAME "DotNetRuntimeContractDescriptor" INTERFACE_TARGET runtime_descriptor_interface EXPORT_VISIBLE) @@ -28,7 +27,6 @@ add_dependencies(gc_wks_descriptor_interface cee_wks_core) generate_data_descriptors( LIBRARY_NAME gc_wks_descriptor CONTRACT_NAME "GCContractDescriptorWKS" - CONTRACT_FILE "${GC_DESCRIPTOR_DIR}/contracts.jsonc" INTERFACE_TARGET gc_wks_descriptor_interface) if (FEATURE_SVR_GC) @@ -41,6 +39,5 @@ if (FEATURE_SVR_GC) generate_data_descriptors( LIBRARY_NAME gc_svr_descriptor CONTRACT_NAME "GCContractDescriptorSVR" - CONTRACT_FILE "${GC_DESCRIPTOR_DIR}/contracts.jsonc" INTERFACE_TARGET gc_svr_descriptor_interface) endif() diff --git a/src/coreclr/vm/datadescriptor/contracts.jsonc b/src/coreclr/vm/datadescriptor/contracts.jsonc deleted file mode 100644 index 1a362675786699..00000000000000 --- a/src/coreclr/vm/datadescriptor/contracts.jsonc +++ /dev/null @@ -1,28 +0,0 @@ -//algorithmic contracts for coreclr -// The format of this file is: JSON with comments -// { -// "CONTRACT NAME": VERSION, -// ... -// } -// CONTRACT NAME is an arbitrary string, VERSION is an integer -// -// cdac-build-tool can take multiple "-c contract_file" arguments -// so to conditionally include contracts, put additional contracts in a separate file -{ - "CodeVersions": 1, - "DacStreams": 1, - "DebugInfo": 1, - "EcmaMetadata": 1, - "Exception": 1, - "ExecutionManager": 2, - "Loader": 1, - "Object": 1, - "PlatformMetadata": 1, - "PrecodeStubs": 3, - "ReJIT": 1, - "RuntimeInfo": 1, - "RuntimeTypeSystem": 1, - "StackWalk": 1, - "StressLog": 2, - "Thread": 1 -} diff --git a/src/coreclr/vm/datadescriptor/datadescriptor.h b/src/coreclr/vm/datadescriptor/datadescriptor.h index 62a4c504b1bbf1..651975ba0cc4c7 100644 --- a/src/coreclr/vm/datadescriptor/datadescriptor.h +++ b/src/coreclr/vm/datadescriptor/datadescriptor.h @@ -12,6 +12,7 @@ #include #include "cdacplatformmetadata.hpp" +#include "interoplibinterface_comwrappers.h" #include "methodtable.h" #include "threads.h" #include "vars.hpp" diff --git a/src/coreclr/vm/datadescriptor/datadescriptor.inc b/src/coreclr/vm/datadescriptor/datadescriptor.inc index 3f0922594a8199..064650a3c23bc2 100644 --- a/src/coreclr/vm/datadescriptor/datadescriptor.inc +++ b/src/coreclr/vm/datadescriptor/datadescriptor.inc @@ -144,10 +144,12 @@ CDAC_TYPE_INDETERMINATE(SyncBlock) CDAC_TYPE_FIELD(SyncBlock, /*pointer*/, InteropInfo, cdac_data::InteropInfo) CDAC_TYPE_END(SyncBlock) +#ifdef FEATURE_COMWRAPPERS CDAC_TYPE_BEGIN(NativeObjectWrapperObject) CDAC_TYPE_INDETERMINATE(NativeObjectWrapperObject) CDAC_TYPE_FIELD(NativeObjectWrapperObject, /*pointer*/, ExternalComObject, cdac_data::ExternalComObject) CDAC_TYPE_END(NativeObjectWrapperObject) +#endif // FEATURE_COMWRAPPERS CDAC_TYPE_BEGIN(SyncTableEntry) CDAC_TYPE_SIZE(sizeof(SyncTableEntry)) @@ -996,7 +998,7 @@ CDAC_GLOBAL_POINTER(TlsIndexBase, &::_tls_index) #endif // TARGET_WINDOWS #ifdef STRESS_LOG CDAC_GLOBAL(StressLogEnabled, uint8, 1) -CDAC_GLOBAL_POINTER(StressLog, &g_pStressLog) +CDAC_GLOBAL_POINTER(StressLogPtr, &g_pStressLog) CDAC_GLOBAL(StressLogHasModuleTable, uint8, 1) CDAC_GLOBAL(StressLogMaxModules, uint64, cdac_offsets::MAX_MODULES) CDAC_GLOBAL(StressLogChunkSize, uint32, STRESSLOG_CHUNK_SIZE) @@ -1006,7 +1008,7 @@ CDAC_GLOBAL(StressLogMaxMessageSize, uint64, (uint64_t)StressMsg::maxMsgSize) CDAC_GLOBAL(StressLogEnabled, uint8, 0) #endif CDAC_GLOBAL_POINTER(ExecutionManagerCodeRangeMapAddress, cdac_data::CodeRangeMapAddress) -CDAC_GLOBAL_POINTER(PlatformMetadata, &::g_cdacPlatformMetadata) +CDAC_GLOBAL_POINTER(PlatformMetadataPtr, &::g_cdacPlatformMetadata) CDAC_GLOBAL_POINTER(ProfilerControlBlock, &::g_profControlBlock) CDAC_GLOBAL_POINTER(MethodDescSizeTable, &MethodDesc::s_ClassificationSizeTable) @@ -1015,4 +1017,24 @@ CDAC_GLOBAL_POINTER(GCHighestAddress, &g_highest_address) CDAC_GLOBAL_SUB_DESCRIPTOR(GC, &(g_gc_dac_vars.gc_descriptor)) +CDAC_GLOBAL_CONTRACT(CodeVersions, 1) +#ifdef FEATURE_COMWRAPPERS +CDAC_GLOBAL_CONTRACT(ComWrappers, 1) +#endif // FEATURE_COMWRAPPERS +CDAC_GLOBAL_CONTRACT(DacStreams, 1) +CDAC_GLOBAL_CONTRACT(DebugInfo, 1) +CDAC_GLOBAL_CONTRACT(EcmaMetadata, 1) +CDAC_GLOBAL_CONTRACT(Exception, 1) +CDAC_GLOBAL_CONTRACT(ExecutionManager, 2) +CDAC_GLOBAL_CONTRACT(Loader, 1) +CDAC_GLOBAL_CONTRACT(Object, 1) +CDAC_GLOBAL_CONTRACT(PlatformMetadata, 1) +CDAC_GLOBAL_CONTRACT(PrecodeStubs, 3) +CDAC_GLOBAL_CONTRACT(ReJIT, 1) +CDAC_GLOBAL_CONTRACT(RuntimeInfo, 1) +CDAC_GLOBAL_CONTRACT(RuntimeTypeSystem, 1) +CDAC_GLOBAL_CONTRACT(StackWalk, 1) +CDAC_GLOBAL_CONTRACT(StressLog, 2) +CDAC_GLOBAL_CONTRACT(Thread, 1) + CDAC_GLOBALS_END() diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IComWrappers.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IComWrappers.cs index 350634bea81fe6..257012cb5528e0 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IComWrappers.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IComWrappers.cs @@ -8,7 +8,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts; public interface IComWrappers : IContract { static string IContract.Name { get; } = nameof(ComWrappers); - TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw) => throw new NotImplementedException(); + TargetPointer GetComWrappersIdentity(TargetPointer address) => throw new NotImplementedException(); } public readonly struct ComWrappers : IComWrappers diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IObject.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IObject.cs index 37e040f6099382..7566ddacc1e488 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IObject.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IObject.cs @@ -12,7 +12,6 @@ public interface IObject : IContract string GetStringValue(TargetPointer address) => throw new NotImplementedException(); TargetPointer GetArrayData(TargetPointer address, out uint count, out TargetPointer boundsStart, out TargetPointer lowerBounds) => throw new NotImplementedException(); bool GetBuiltInComData(TargetPointer address, out TargetPointer rcw, out TargetPointer ccw) => throw new NotImplementedException(); - TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw) => throw new NotImplementedException(); } public readonly struct Object : IObject diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs index 3ea7cdfa963a2f..5fc463ce2ec53a 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs @@ -35,7 +35,7 @@ public static class Globals public const string StressLogEnabled = nameof(StressLogEnabled); public const string StressLogHasModuleTable = nameof(StressLogHasModuleTable); - public const string StressLog = nameof(StressLog); + public const string StressLogPtr = nameof(StressLogPtr); public const string StressLogModuleTable = nameof(StressLogModuleTable); public const string StressLogMaxModules = nameof(StressLogMaxModules); public const string StressLogChunkMaxSize = nameof(StressLogChunkMaxSize); @@ -62,7 +62,7 @@ public static class Globals public const string NumberOfTlsOffsetsNotUsedInNoncollectibleArray = nameof(NumberOfTlsOffsetsNotUsedInNoncollectibleArray); public const string MaxClrNotificationArgs = nameof(MaxClrNotificationArgs); public const string ClrNotificationArguments = nameof(ClrNotificationArguments); - public const string PlatformMetadata = nameof(PlatformMetadata); + public const string PlatformMetadataPtr = nameof(PlatformMetadataPtr); public const string ProfilerControlBlock = nameof(ProfilerControlBlock); public const string MethodDescSizeTable = nameof(MethodDescSizeTable); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappers_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappers_1.cs index ba51cc174711f7..c2faad4bb180fa 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappers_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappers_1.cs @@ -17,9 +17,9 @@ public ComWrappers_1(Target target) _target = target; } - public TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw) + public TargetPointer GetComWrappersIdentity(TargetPointer address) { - Data.NativeObjectWrapperObject wrapper = _target.ProcessedData.GetOrAdd(rcw); + Data.NativeObjectWrapperObject wrapper = _target.ProcessedData.GetOrAdd(address); return wrapper.ExternalComObject; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadataFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadataFactory.cs index 438b0a93788f53..aa6b9fc3bbfd6d 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadataFactory.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadataFactory.cs @@ -9,7 +9,7 @@ public sealed class PlatformMetadataFactory : IContractFactory.CreateContract(Target target, int version) { - TargetPointer cdacMetadataAddress = target.ReadGlobalPointer(Constants.Globals.PlatformMetadata); + TargetPointer cdacMetadataAddress = target.ReadGlobalPointer(Constants.Globals.PlatformMetadataPtr); Data.PlatformMetadata cdacMetadata = target.ProcessedData.GetOrAdd(cdacMetadataAddress); return version switch { diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs index 7940f14b7faa7f..68e61e3bde1744 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs @@ -45,7 +45,7 @@ public StressLogData GetStressLogData() return default; } - return GetStressLogData(target.ReadGlobalPointer(Constants.Globals.StressLog)); + return GetStressLogData(target.ReadGlobalPointer(Constants.Globals.StressLogPtr)); } public StressLogData GetStressLogData(TargetPointer stressLogPointer) @@ -108,14 +108,14 @@ private TargetPointer GetFormatPointer(ulong formatOffset) { if (target.ReadGlobal(Constants.Globals.StressLogHasModuleTable) == 0) { - Data.StressLog stressLog = target.ProcessedData.GetOrAdd(target.ReadGlobalPointer(Constants.Globals.StressLog)); + Data.StressLog stressLog = target.ProcessedData.GetOrAdd(target.ReadGlobalPointer(Constants.Globals.StressLogPtr)); return new TargetPointer(stressLog.ModuleOffset.Value + formatOffset); } TargetPointer? moduleTable; if (!target.TryReadGlobalPointer(Constants.Globals.StressLogModuleTable, out moduleTable)) { - if (!target.TryReadGlobalPointer(Constants.Globals.StressLog, out TargetPointer? pStressLog)) + if (!target.TryReadGlobalPointer(Constants.Globals.StressLogPtr, out TargetPointer? pStressLog)) { throw new InvalidOperationException("StressLogModuleTable is not set and StressLog is not available, but StressLogHasModuleTable is set to 1."); } diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs index 30575e2f768892..5c27d035ac430c 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs @@ -2515,7 +2515,7 @@ int ISOSDacInterface.GetStackReferences(int osThreadID, void** ppEnum) int ISOSDacInterface.GetStressLogAddress(ClrDataAddress* stressLog) { - ulong stressLogAddress = _target.ReadGlobalPointer(Constants.Globals.StressLog); + ulong stressLogAddress = _target.ReadGlobalPointer(Constants.Globals.StressLogPtr); #if DEBUG if (_legacyImpl is not null) @@ -3117,28 +3117,32 @@ int ISOSDacInterface10.IsComWrappersRCW(ClrDataAddress rcw, Interop.BOOL* isComW int ISOSDacInterface10.GetComWrappersRCWData(ClrDataAddress rcw, ClrDataAddress* identity) { int hr = HResults.S_OK; - if (_target.ReadGlobalPointer(Constants.Globals.FeatureCOMWrappers) == 0) - hr = HResults.E_NOTIMPL; - else if (rcw == 0) - hr = HResults.E_INVALIDARG; - else if ((rcw & ComWrappersConstants.rcwMask) == 0) - *identity = 0; - else + Contracts.IComWrappers comWrappersContract; + try { - try - { - if (identity != null) - { - Contracts.IComWrappers comWrappersContract = _target.Contracts.ComWrappers; - TargetPointer identityPtr = comWrappersContract.GetComWrappersRCWIdentity((rcw.ToTargetPointer(_target) & ~(ComWrappersConstants.rcwMask))); - *identity = identityPtr.ToClrDataAddress(_target); - } - } - catch (System.Exception ex) + comWrappersContract = _target.Contracts.ComWrappers; + } + catch (System.Exception) + { + return HResults.E_NOTIMPL; // we return directly here because the legacy DAC method is empty so we can't compare + } + + try + { + if (rcw == 0 || identity == null) + throw new ArgumentException(); + else if ((rcw & ComWrappersConstants.rcwMask) == 0) + *identity = 0; + else if (identity != null) { - hr = ex.HResult; + TargetPointer identityPtr = comWrappersContract.GetComWrappersIdentity((rcw.ToTargetPointer(_target) & ~(ComWrappersConstants.rcwMask))); + *identity = identityPtr.ToClrDataAddress(_target); } } + catch (System.Exception ex) + { + hr = ex.HResult; + } #if DEBUG if (_legacyImpl10 is not null) { diff --git a/src/native/managed/cdac/tests/PrecodeStubsTests.cs b/src/native/managed/cdac/tests/PrecodeStubsTests.cs index cbab72d9e3d729..279d91584c39f1 100644 --- a/src/native/managed/cdac/tests/PrecodeStubsTests.cs +++ b/src/native/managed/cdac/tests/PrecodeStubsTests.cs @@ -350,7 +350,7 @@ private static Target CreateTarget(PrecodeBuilder precodeBuilder) var arch = precodeBuilder.Builder.TargetTestHelpers.Arch; TestPlaceholderTarget.ReadFromTargetDelegate reader = precodeBuilder.Builder.GetMemoryContext().ReadFromTarget; // hack for this test put the precode machine descriptor at the same address as the PlatformMetadata - (string Name, ulong Value)[] globals = [(Constants.Globals.PlatformMetadata, precodeBuilder.MachineDescriptorAddress)]; + (string Name, ulong Value)[] globals = [(Constants.Globals.PlatformMetadataPtr, precodeBuilder.MachineDescriptorAddress)]; var target = new TestPlaceholderTarget(arch, reader, precodeBuilder.Types, globals); IContractFactory precodeFactory = new PrecodeStubsFactory(); From ee224cd6b1159f9557ba8b11df162d5c8b930150 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Mon, 15 Sep 2025 11:47:13 -0700 Subject: [PATCH 4/7] docs --- docs/design/datacontracts/Object.md | 9 --------- docs/design/datacontracts/debug_interface_globals.md | 1 - 2 files changed, 10 deletions(-) diff --git a/docs/design/datacontracts/Object.md b/docs/design/datacontracts/Object.md index 18b6d0c9befe18..18747df027df3c 100644 --- a/docs/design/datacontracts/Object.md +++ b/docs/design/datacontracts/Object.md @@ -125,13 +125,4 @@ bool GetBuiltInComData(TargetPointer address, out TargetPointer rcw, out TargetP ccw = target.ReadPointer(interopInfo + /* InteropSyncBlockInfo::CCW offset */); return rcw != TargetPointer.Null && ccw != TargetPointer.Null; } - -TargetPointer GetComWrappersRCWIdentity(TargetPointer rcw) -{ - if ((rcw.Value & 1) == 0) - { - return TargetPointer.Null; - } - return target.ReadPointer(new TargetPointer(rcw.Value & ~1UL) + /* NativeObjectWrapperObject::ExternalComObject offset */); -} ``` diff --git a/docs/design/datacontracts/debug_interface_globals.md b/docs/design/datacontracts/debug_interface_globals.md index f36acaff88f7aa..c4d1348f138ce0 100644 --- a/docs/design/datacontracts/debug_interface_globals.md +++ b/docs/design/datacontracts/debug_interface_globals.md @@ -20,4 +20,3 @@ Global variables used | MaxClrNotificationArgs | uint32 | Identify the maximum number of CLR notification arguments | | ClrNotificationArguments | TargetPointer | Identify where the ClrNotificationArguments exists | | DefaultADID | uint | Identify the default AppDomain ID | -| FeatureCOMWrappers | uint8 | Flag for if FeatureCOMWrappers is disabled (0) or enabled (1) | From d8b11bab988a0dbfb56fd908dcdffcf4c04f1358 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Mon, 15 Sep 2025 14:34:19 -0700 Subject: [PATCH 5/7] fix logging --- .../ContractDescriptorTarget.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs index c392e71e368aa3..bec5c1cb7dc3f1 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs @@ -772,12 +772,6 @@ public Target.TypeInfo GetTypeInfo(string type) internal bool TryGetContractVersion(string contractName, out int version) { - foreach (var kvp in _contracts) - { - var name = kvp.Key; - var value = kvp.Value; - Console.WriteLine($"Contract: {name}, Version: {value}"); - } return _contracts.TryGetValue(contractName, out version); } From 7c447fac5c261ee24a0538dec262447303e4e358 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Mon, 15 Sep 2025 15:24:18 -0700 Subject: [PATCH 6/7] codereview --- .../datadescriptor-shared/datadescriptor.cpp | 4 ++-- .../tools/cdac-build-tool/ObjectFileScraper.cs | 17 +++++++++-------- .../Contracts/ComWrappers_1.cs | 2 +- .../Legacy/ISOSDacInterface.cs | 6 ------ .../mscordaccore_universal/Legacy/SOSDacImpl.cs | 16 ++++------------ 5 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp b/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp index 4206f89277bb1c..461ffdb62e4d9e 100644 --- a/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp +++ b/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp @@ -242,7 +242,7 @@ struct BinaryBlobDataDescriptor uint32_t GlobalStringValuesStart; uint32_t GlobalSubDescriptorsStart; - uint32_t ContractsStart; + uint32_t GlobalContractsStart; uint32_t NamesPoolStart; uint32_t TypeCount; @@ -298,7 +298,7 @@ struct MagicAndBlob BlobDataDescriptor = { /* .GlobalPointersStart = */ offsetof(struct BinaryBlobDataDescriptor, GlobalPointerValues), /* .GlobalStringValuesStart = */ offsetof(struct BinaryBlobDataDescriptor, GlobalStringValues), /* .GlobalSubDescriptorsStart = */ offsetof(struct BinaryBlobDataDescriptor, GlobalSubDescriptorValues), - /* .ContractsStart = */ offsetof(struct BinaryBlobDataDescriptor, GlobalContractValues), + /* .GlobalContractsStart = */ offsetof(struct BinaryBlobDataDescriptor, GlobalContractValues), /* .NamesPoolStart = */ offsetof(struct BinaryBlobDataDescriptor, NamesPool), /* .TypeCount = */ CDacBlobTypesCount, /* .FieldsPoolCount = */ CDacBlobFieldsPoolCount, diff --git a/src/coreclr/tools/cdac-build-tool/ObjectFileScraper.cs b/src/coreclr/tools/cdac-build-tool/ObjectFileScraper.cs index a8481e22f8541d..ead89efcf89a7b 100644 --- a/src/coreclr/tools/cdac-build-tool/ObjectFileScraper.cs +++ b/src/coreclr/tools/cdac-build-tool/ObjectFileScraper.cs @@ -163,7 +163,7 @@ private struct HeaderDirectory public uint GlobalStringValuesStart; public uint GlobalSubDescriptorsStart; - public uint ContractsStart; + public uint GlobalContractsStart; public uint NamesStart; public uint TypesCount; @@ -222,25 +222,26 @@ private static HeaderDirectory ReadHeader(ScraperState state) var globalStringValuesStart = state.ReadUInt32(); var globalSubDescriptorsStart = state.ReadUInt32(); - var contractsStart = state.ReadUInt32(); - var namesStart = state.ReadUInt32(); + var globalContractsStart = state.ReadUInt32(); + var namesStart = state.ReadUInt32(); var typeCount = state.ReadUInt32(); - var fieldPoolCount = state.ReadUInt32(); + var fieldPoolCount = state.ReadUInt32(); var globalLiteralValuesCount = state.ReadUInt32(); - var globalPointerValuesCount = state.ReadUInt32(); + var globalPointerValuesCount = state.ReadUInt32(); var globalStringValuesCount = state.ReadUInt32(); + var globalSubDescriptorsCount = state.ReadUInt32(); var globalContractsCount = state.ReadUInt32(); var namesPoolCount = state.ReadUInt32(); - var typeSpecSize = state.ReadByte(); var fieldSpecSize = state.ReadByte(); var globalLiteralSpecSize = state.ReadByte(); var globalPointerSpecSize = state.ReadByte(); + var globalStringSpecSize = state.ReadByte(); return new HeaderDirectory { @@ -251,7 +252,7 @@ private static HeaderDirectory ReadHeader(ScraperState state) GlobalPointersStart = globalPointersStart, GlobalStringValuesStart = globalStringValuesStart, GlobalSubDescriptorsStart = globalSubDescriptorsStart, - ContractsStart = contractsStart, + GlobalContractsStart = globalContractsStart, NamesStart = namesStart, TypesCount = typeCount, @@ -620,7 +621,7 @@ private static GlobalPointerSpec[] ReadGlobalSubDescriptorSpecs(ScraperState sta private static GlobalContractSpec[] ReadGlobalContractSpecs(ScraperState state, HeaderDirectory header) { GlobalContractSpec[] globalSpecs = new GlobalContractSpec[header.GlobalContractsCount]; - state.ResetPosition(state.HeaderStart + (long)header.ContractsStart); + state.ResetPosition(state.HeaderStart + (long)header.GlobalContractsStart); for (int i = 0; i < header.GlobalContractsCount; i++) { int bytesRead = 0; diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappers_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappers_1.cs index c2faad4bb180fa..98b0a54dc0c416 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappers_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappers_1.cs @@ -8,7 +8,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts; -internal readonly partial struct ComWrappers_1 : IComWrappers +internal readonly struct ComWrappers_1 : IComWrappers { private readonly Target _target; diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/ISOSDacInterface.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/ISOSDacInterface.cs index cca193efeaac23..3ee717a392cace 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/ISOSDacInterface.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/ISOSDacInterface.cs @@ -11,12 +11,6 @@ namespace Microsoft.Diagnostics.DataContractReader.Legacy; // See src/coreclr/inc/sospriv.idl #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value - -internal struct ComWrappersConstants -{ - public const ulong rcwMask = 1UL; -} - internal enum CLRDataOtherNotifyFlag { CLRDATA_NOTIFY_ON_MODULE_LOAD = 0x1, diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs index 7347c8393bfb32..65daf4ded7917a 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs @@ -3308,25 +3308,17 @@ int ISOSDacInterface10.IsComWrappersRCW(ClrDataAddress rcw, Interop.BOOL* isComW int ISOSDacInterface10.GetComWrappersRCWData(ClrDataAddress rcw, ClrDataAddress* identity) { int hr = HResults.S_OK; - Contracts.IComWrappers comWrappersContract; - try - { - comWrappersContract = _target.Contracts.ComWrappers; - } - catch (System.Exception) - { - return HResults.E_NOTIMPL; // we return directly here because the legacy DAC method is empty so we can't compare - } - try { + ulong rcwMask = 1UL; + Contracts.IComWrappers comWrappersContract = _target.Contracts.ComWrappers; if (rcw == 0 || identity == null) throw new ArgumentException(); - else if ((rcw & ComWrappersConstants.rcwMask) == 0) + else if ((rcw & rcwMask) == 0) *identity = 0; else if (identity != null) { - TargetPointer identityPtr = comWrappersContract.GetComWrappersIdentity((rcw.ToTargetPointer(_target) & ~(ComWrappersConstants.rcwMask))); + TargetPointer identityPtr = comWrappersContract.GetComWrappersIdentity((rcw.ToTargetPointer(_target) & ~rcwMask)); *identity = identityPtr.ToClrDataAddress(_target); } } From 3228c7d47432f60f0a2920211ed62952dc0da83e Mon Sep 17 00:00:00 2001 From: rcj1 Date: Tue, 16 Sep 2025 18:07:16 -0700 Subject: [PATCH 7/7] allow duplicate contract and global names --- src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp | 6 ++++-- src/coreclr/vm/datadescriptor/datadescriptor.inc | 4 ++-- .../Constants.cs | 4 ++-- .../Contracts/PlatformMetadataFactory.cs | 2 +- .../Contracts/StressLog.cs | 6 +++--- .../cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs | 2 +- src/native/managed/cdac/tests/PrecodeStubsTests.cs | 2 +- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp b/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp index 461ffdb62e4d9e..616a4d96f1d9ff 100644 --- a/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp +++ b/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp @@ -62,6 +62,7 @@ struct GlobalContractSpec #define MAKE_FIELDLEN_NAME(tyname,membername) CONCAT4(cdac_string_pool_membername__, tyname, __, membername) #define MAKE_FIELDTYPELEN_NAME(tyname,membername) CONCAT4(cdac_string_pool_membertypename__, tyname, __, membername) #define MAKE_GLOBALLEN_NAME(globalname) CONCAT(cdac_string_pool_globalname__, globalname) +#define MAKE_GLOBALCONTRACTLEN_NAME(globalname) CONCAT(cdac_string_pool_globalcontractname__, globalname) #define MAKE_GLOBALTYPELEN_NAME(globalname) CONCAT(cdac_string_pool_globaltypename__, globalname) #define MAKE_GLOBALVALUELEN_NAME(globalname) CONCAT(cdac_string_pool_globalvalue__, globalname) @@ -84,7 +85,7 @@ struct CDacStringPoolSizes DECL_LEN(MAKE_GLOBALVALUELEN_NAME(name), sizeof(STRINGIFY(stringval))) #define CDAC_GLOBAL_POINTER(name,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) #define CDAC_GLOBAL_SUB_DESCRIPTOR(name,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) -#define CDAC_GLOBAL_CONTRACT(name,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) +#define CDAC_GLOBAL_CONTRACT(name,value) DECL_LEN(MAKE_GLOBALCONTRACTLEN_NAME(name), sizeof(#name)) #define CDAC_GLOBAL(name,tyname,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) \ DECL_LEN(MAKE_GLOBALTYPELEN_NAME(name), sizeof(#tyname)) #include "wrappeddatadescriptor.inc" @@ -97,6 +98,7 @@ struct CDacStringPoolSizes #define GET_FIELDTYPE_NAME(tyname,membername) offsetof(struct CDacStringPoolSizes, MAKE_FIELDTYPELEN_NAME(tyname,membername)) #define GET_GLOBAL_NAME(globalname) offsetof(struct CDacStringPoolSizes, MAKE_GLOBALLEN_NAME(globalname)) #define GET_GLOBALTYPE_NAME(globalname) offsetof(struct CDacStringPoolSizes, MAKE_GLOBALTYPELEN_NAME(globalname)) +#define GET_GLOBALCONTRACT_NAME(globalname) offsetof(struct CDacStringPoolSizes, MAKE_GLOBALCONTRACTLEN_NAME(globalname)) #define GET_GLOBALSTRING_VALUE(globalname) offsetof(struct CDacStringPoolSizes, MAKE_GLOBALVALUELEN_NAME(globalname)) // count the types @@ -359,7 +361,7 @@ struct MagicAndBlob BlobDataDescriptor = { }, /* .GlobalContractValues = */ { -#define CDAC_GLOBAL_CONTRACT(name,value) { /* .Name = */ GET_GLOBAL_NAME(name), /* .Version = */ value }, +#define CDAC_GLOBAL_CONTRACT(name,value) { /* .Name = */ GET_GLOBALCONTRACT_NAME(name), /* .Version = */ value }, #include "wrappeddatadescriptor.inc" }, diff --git a/src/coreclr/vm/datadescriptor/datadescriptor.inc b/src/coreclr/vm/datadescriptor/datadescriptor.inc index 715f12a25ef399..3844f70514e612 100644 --- a/src/coreclr/vm/datadescriptor/datadescriptor.inc +++ b/src/coreclr/vm/datadescriptor/datadescriptor.inc @@ -1017,7 +1017,7 @@ CDAC_GLOBAL_POINTER(TlsIndexBase, &::_tls_index) #endif // TARGET_WINDOWS #ifdef STRESS_LOG CDAC_GLOBAL(StressLogEnabled, uint8, 1) -CDAC_GLOBAL_POINTER(StressLogPtr, &g_pStressLog) +CDAC_GLOBAL_POINTER(StressLog, &g_pStressLog) CDAC_GLOBAL(StressLogHasModuleTable, uint8, 1) CDAC_GLOBAL(StressLogMaxModules, uint64, cdac_offsets::MAX_MODULES) CDAC_GLOBAL(StressLogChunkSize, uint32, STRESSLOG_CHUNK_SIZE) @@ -1027,7 +1027,7 @@ CDAC_GLOBAL(StressLogMaxMessageSize, uint64, (uint64_t)StressMsg::maxMsgSize) CDAC_GLOBAL(StressLogEnabled, uint8, 0) #endif CDAC_GLOBAL_POINTER(ExecutionManagerCodeRangeMapAddress, cdac_data::CodeRangeMapAddress) -CDAC_GLOBAL_POINTER(PlatformMetadataPtr, &::g_cdacPlatformMetadata) +CDAC_GLOBAL_POINTER(PlatformMetadata, &::g_cdacPlatformMetadata) CDAC_GLOBAL_POINTER(ProfilerControlBlock, &::g_profControlBlock) CDAC_GLOBAL_POINTER(MethodDescSizeTable, &MethodDesc::s_ClassificationSizeTable) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs index 0eaca5ca312d63..084afe879f99c1 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs @@ -35,7 +35,7 @@ public static class Globals public const string StressLogEnabled = nameof(StressLogEnabled); public const string StressLogHasModuleTable = nameof(StressLogHasModuleTable); - public const string StressLogPtr = nameof(StressLogPtr); + public const string StressLog = nameof(StressLog); public const string StressLogModuleTable = nameof(StressLogModuleTable); public const string StressLogMaxModules = nameof(StressLogMaxModules); public const string StressLogChunkMaxSize = nameof(StressLogChunkMaxSize); @@ -63,7 +63,7 @@ public static class Globals public const string NumberOfTlsOffsetsNotUsedInNoncollectibleArray = nameof(NumberOfTlsOffsetsNotUsedInNoncollectibleArray); public const string MaxClrNotificationArgs = nameof(MaxClrNotificationArgs); public const string ClrNotificationArguments = nameof(ClrNotificationArguments); - public const string PlatformMetadataPtr = nameof(PlatformMetadataPtr); + public const string PlatformMetadata = nameof(PlatformMetadata); public const string ProfilerControlBlock = nameof(ProfilerControlBlock); public const string MethodDescSizeTable = nameof(MethodDescSizeTable); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadataFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadataFactory.cs index aa6b9fc3bbfd6d..438b0a93788f53 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadataFactory.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadataFactory.cs @@ -9,7 +9,7 @@ public sealed class PlatformMetadataFactory : IContractFactory.CreateContract(Target target, int version) { - TargetPointer cdacMetadataAddress = target.ReadGlobalPointer(Constants.Globals.PlatformMetadataPtr); + TargetPointer cdacMetadataAddress = target.ReadGlobalPointer(Constants.Globals.PlatformMetadata); Data.PlatformMetadata cdacMetadata = target.ProcessedData.GetOrAdd(cdacMetadataAddress); return version switch { diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs index 68e61e3bde1744..7940f14b7faa7f 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs @@ -45,7 +45,7 @@ public StressLogData GetStressLogData() return default; } - return GetStressLogData(target.ReadGlobalPointer(Constants.Globals.StressLogPtr)); + return GetStressLogData(target.ReadGlobalPointer(Constants.Globals.StressLog)); } public StressLogData GetStressLogData(TargetPointer stressLogPointer) @@ -108,14 +108,14 @@ private TargetPointer GetFormatPointer(ulong formatOffset) { if (target.ReadGlobal(Constants.Globals.StressLogHasModuleTable) == 0) { - Data.StressLog stressLog = target.ProcessedData.GetOrAdd(target.ReadGlobalPointer(Constants.Globals.StressLogPtr)); + Data.StressLog stressLog = target.ProcessedData.GetOrAdd(target.ReadGlobalPointer(Constants.Globals.StressLog)); return new TargetPointer(stressLog.ModuleOffset.Value + formatOffset); } TargetPointer? moduleTable; if (!target.TryReadGlobalPointer(Constants.Globals.StressLogModuleTable, out moduleTable)) { - if (!target.TryReadGlobalPointer(Constants.Globals.StressLogPtr, out TargetPointer? pStressLog)) + if (!target.TryReadGlobalPointer(Constants.Globals.StressLog, out TargetPointer? pStressLog)) { throw new InvalidOperationException("StressLogModuleTable is not set and StressLog is not available, but StressLogHasModuleTable is set to 1."); } diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs index 53216595bc8426..157406337bbd22 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs @@ -2600,7 +2600,7 @@ int ISOSDacInterface.GetStackReferences(int osThreadID, void** ppEnum) int ISOSDacInterface.GetStressLogAddress(ClrDataAddress* stressLog) { - ulong stressLogAddress = _target.ReadGlobalPointer(Constants.Globals.StressLogPtr); + ulong stressLogAddress = _target.ReadGlobalPointer(Constants.Globals.StressLog); #if DEBUG if (_legacyImpl is not null) diff --git a/src/native/managed/cdac/tests/PrecodeStubsTests.cs b/src/native/managed/cdac/tests/PrecodeStubsTests.cs index 279d91584c39f1..cbab72d9e3d729 100644 --- a/src/native/managed/cdac/tests/PrecodeStubsTests.cs +++ b/src/native/managed/cdac/tests/PrecodeStubsTests.cs @@ -350,7 +350,7 @@ private static Target CreateTarget(PrecodeBuilder precodeBuilder) var arch = precodeBuilder.Builder.TargetTestHelpers.Arch; TestPlaceholderTarget.ReadFromTargetDelegate reader = precodeBuilder.Builder.GetMemoryContext().ReadFromTarget; // hack for this test put the precode machine descriptor at the same address as the PlatformMetadata - (string Name, ulong Value)[] globals = [(Constants.Globals.PlatformMetadataPtr, precodeBuilder.MachineDescriptorAddress)]; + (string Name, ulong Value)[] globals = [(Constants.Globals.PlatformMetadata, precodeBuilder.MachineDescriptorAddress)]; var target = new TestPlaceholderTarget(arch, reader, precodeBuilder.Types, globals); IContractFactory precodeFactory = new PrecodeStubsFactory();