Skip to content

Commit c5f8cda

Browse files
Copilotrcj1
andcommitted
cDAC: Implement ISOSDacInterface::GetRCWData
Co-authored-by: rcj1 <77995559+rcj1@users.noreply.github.com>
1 parent a4cb8e4 commit c5f8cda

File tree

2 files changed

+82
-3
lines changed

2 files changed

+82
-3
lines changed

src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ISOSDacInterface.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,27 @@ public struct DacpCOMInterfacePointerData
394394
public ClrDataAddress comContext;
395395
}
396396

397+
// Mirrors struct DacpRCWData in src/coreclr/inc/dacprivate.h.
398+
// Size must remain 0x58 bytes (enforced by static_assert in the native code).
399+
public struct DacpRCWData
400+
{
401+
public ClrDataAddress identityPointer;
402+
public ClrDataAddress unknownPointer;
403+
public ClrDataAddress managedObject;
404+
public ClrDataAddress jupiterObject;
405+
public ClrDataAddress vtablePtr;
406+
public ClrDataAddress creatorThread;
407+
public ClrDataAddress ctxCookie;
408+
public int refCount;
409+
public int interfaceCount;
410+
public int isJupiterObject; // BOOL
411+
public int supportsIInspectable; // BOOL
412+
public int isAggregated; // BOOL
413+
public int isContained; // BOOL
414+
public int isFreeThreaded; // BOOL
415+
public int isDisconnected; // BOOL
416+
}
417+
397418
[GeneratedComInterface]
398419
[Guid("286CA186-E763-4F61-9760-487D43AE4341")]
399420
public unsafe partial interface ISOSEnum
@@ -758,7 +779,7 @@ public unsafe partial interface ISOSDacInterface
758779

759780
// COM
760781
[PreserveSig]
761-
int GetRCWData(ClrDataAddress addr, /*struct DacpRCWData */ void* data);
782+
int GetRCWData(ClrDataAddress addr, DacpRCWData* data);
762783
[PreserveSig]
763784
int GetRCWInterfaces(ClrDataAddress rcw, uint count, [In, Out, MarshalUsing(CountElementName = nameof(count))] DacpCOMInterfacePointerData[]? interfaces, uint* pNeeded);
764785
[PreserveSig]

src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3388,8 +3388,66 @@ int ISOSDacInterface.GetPrivateBinPaths(ClrDataAddress appDomain, int count, cha
33883388

33893389
return hr;
33903390
}
3391-
int ISOSDacInterface.GetRCWData(ClrDataAddress addr, void* data)
3392-
=> _legacyImpl is not null ? _legacyImpl.GetRCWData(addr, data) : HResults.E_NOTIMPL;
3391+
int ISOSDacInterface.GetRCWData(ClrDataAddress addr, DacpRCWData* data)
3392+
{
3393+
int hr = HResults.S_OK;
3394+
try
3395+
{
3396+
if (addr == 0)
3397+
throw new ArgumentException();
3398+
if (data is null)
3399+
throw new ArgumentException();
3400+
3401+
*data = default;
3402+
3403+
TargetPointer rcwPtr = addr.ToTargetPointer(_target);
3404+
IBuiltInCOM builtInCom = _target.Contracts.BuiltInCOM;
3405+
Contracts.RCWData rcwData = builtInCom.GetRCWData(rcwPtr);
3406+
3407+
data->identityPointer = rcwData.IdentityPointer.ToClrDataAddress(_target);
3408+
data->unknownPointer = rcwData.UnknownPointer.ToClrDataAddress(_target);
3409+
data->managedObject = rcwData.ManagedObject.ToClrDataAddress(_target);
3410+
data->vtablePtr = rcwData.VTablePtr.ToClrDataAddress(_target);
3411+
data->creatorThread = rcwData.CreatorThread.ToClrDataAddress(_target);
3412+
data->ctxCookie = rcwData.CtxCookie.ToClrDataAddress(_target);
3413+
data->refCount = (int)rcwData.RefCount;
3414+
data->interfaceCount = builtInCom.GetRCWInterfaces(rcwPtr).Count();
3415+
data->isAggregated = rcwData.IsAggregated ? 1 : 0;
3416+
data->isContained = rcwData.IsContained ? 1 : 0;
3417+
data->isFreeThreaded = rcwData.IsFreeThreaded ? 1 : 0;
3418+
data->isDisconnected = rcwData.IsDisconnected ? 1 : 0;
3419+
}
3420+
catch (System.Exception ex)
3421+
{
3422+
hr = ex.HResult;
3423+
}
3424+
3425+
#if DEBUG
3426+
if (_legacyImpl is not null)
3427+
{
3428+
DacpRCWData dataLocal;
3429+
int hrLocal = _legacyImpl.GetRCWData(addr, &dataLocal);
3430+
Debug.ValidateHResult(hr, hrLocal);
3431+
if (hr == HResults.S_OK)
3432+
{
3433+
Debug.Assert(data->identityPointer == dataLocal.identityPointer, $"cDAC: {data->identityPointer:x}, DAC: {dataLocal.identityPointer:x}");
3434+
Debug.Assert(data->unknownPointer == dataLocal.unknownPointer, $"cDAC: {data->unknownPointer:x}, DAC: {dataLocal.unknownPointer:x}");
3435+
Debug.Assert(data->managedObject == dataLocal.managedObject, $"cDAC: {data->managedObject:x}, DAC: {dataLocal.managedObject:x}");
3436+
Debug.Assert(data->vtablePtr == dataLocal.vtablePtr, $"cDAC: {data->vtablePtr:x}, DAC: {dataLocal.vtablePtr:x}");
3437+
Debug.Assert(data->creatorThread == dataLocal.creatorThread, $"cDAC: {data->creatorThread:x}, DAC: {dataLocal.creatorThread:x}");
3438+
Debug.Assert(data->ctxCookie == dataLocal.ctxCookie, $"cDAC: {data->ctxCookie:x}, DAC: {dataLocal.ctxCookie:x}");
3439+
Debug.Assert(data->refCount == dataLocal.refCount, $"cDAC: {data->refCount}, DAC: {dataLocal.refCount}");
3440+
Debug.Assert(data->interfaceCount == dataLocal.interfaceCount, $"cDAC: {data->interfaceCount}, DAC: {dataLocal.interfaceCount}");
3441+
Debug.Assert(data->isAggregated == dataLocal.isAggregated, $"cDAC: {data->isAggregated}, DAC: {dataLocal.isAggregated}");
3442+
Debug.Assert(data->isContained == dataLocal.isContained, $"cDAC: {data->isContained}, DAC: {dataLocal.isContained}");
3443+
Debug.Assert(data->isFreeThreaded == dataLocal.isFreeThreaded, $"cDAC: {data->isFreeThreaded}, DAC: {dataLocal.isFreeThreaded}");
3444+
Debug.Assert(data->isDisconnected == dataLocal.isDisconnected, $"cDAC: {data->isDisconnected}, DAC: {dataLocal.isDisconnected}");
3445+
}
3446+
}
3447+
#endif
3448+
3449+
return hr;
3450+
}
33933451
int ISOSDacInterface.GetRCWInterfaces(ClrDataAddress rcw, uint count, [In, MarshalUsing(CountElementName = nameof(count)), Out] DacpCOMInterfacePointerData[]? interfaces, uint* pNeeded)
33943452
{
33953453
int hr = HResults.S_OK;

0 commit comments

Comments
 (0)