Skip to content

Commit d16e2e8

Browse files
author
Max Charlamb
committed
add DAC like entrypoint
1 parent 74158bc commit d16e2e8

File tree

4 files changed

+124
-2
lines changed

4 files changed

+124
-2
lines changed

src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public static bool TryCreate(
6060
ReadFromTargetDelegate readFromTarget,
6161
GetTargetThreadContextDelegate getThreadContext,
6262
GetTargetPlatformDelegate getTargetPlatform,
63-
out ContractDescriptorTarget? target)
63+
[NotNullWhen(true)] out ContractDescriptorTarget? target)
6464
{
6565
Reader reader = new Reader(readFromTarget, getThreadContext, getTargetPlatform);
6666
if (TryReadContractDescriptor(

src/native/managed/cdacreader/src/Entrypoints.cs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Runtime.InteropServices;
66
using System.Runtime.InteropServices.Marshalling;
7+
using Microsoft.Diagnostics.DataContractReader.Legacy;
78

89
namespace Microsoft.Diagnostics.DataContractReader;
910

@@ -83,4 +84,80 @@ private static unsafe int CreateSosInterface(IntPtr handle, IntPtr legacyImplPtr
8384
*obj = ptr;
8485
return 0;
8586
}
87+
88+
[UnmanagedCallersOnly(EntryPoint = "CLRDataCreateInstance")]
89+
private static unsafe int CLRDataCreateInstance(Guid* pIID, IntPtr /*ICLRDataTarget*/ pLegacyTarget, void** iface)
90+
{
91+
if (pLegacyTarget == IntPtr.Zero || iface == null)
92+
return HResults.E_INVALIDARG;
93+
94+
*iface = null;
95+
96+
ComWrappers cw = new StrategyBasedComWrappers();
97+
object obj = cw.GetOrCreateObjectForComInstance(pLegacyTarget, CreateObjectFlags.None);
98+
ICLRDataTarget dataTarget = obj as ICLRDataTarget ?? throw new ArgumentException($"pLegacyTarget does not implement ${nameof(ICLRDataTarget)}", nameof(pLegacyTarget));
99+
ICLRContractLocator contractLocator = obj as ICLRContractLocator ?? throw new ArgumentException($"pLegacyTarget does not implement ${nameof(ICLRContractLocator)}", nameof(pLegacyTarget));
100+
101+
ulong contractAddress;
102+
if (contractLocator.GetContractDescriptor(&contractAddress) != 0)
103+
{
104+
throw new InvalidOperationException("Unable to retrieve contract address from ICLRContractLocator");
105+
}
106+
107+
if (!ContractDescriptorTarget.TryCreate(
108+
contractAddress,
109+
(address, buffer) =>
110+
{
111+
fixed (byte* bufferPtr = buffer)
112+
{
113+
uint bytesRead;
114+
return dataTarget.ReadVirtual(address, bufferPtr, (uint)buffer.Length, &bytesRead);
115+
}
116+
},
117+
(threadId, contextFlags, contextSize, bufferToFill) =>
118+
{
119+
fixed (byte* bufferPtr = bufferToFill)
120+
{
121+
return dataTarget.GetThreadContext(threadId, contextFlags, contextSize, bufferPtr);
122+
}
123+
},
124+
(out platform) =>
125+
{
126+
platform = 0;
127+
uint machineType;
128+
int hr = dataTarget.GetMachineType(&machineType);
129+
switch (machineType)
130+
{
131+
// ICLRDataTarget can not be used to find OS. For now labeling all platforms as Windows
132+
//
133+
case 0x014c: // IMAGE_FILE_MACHINE_I386
134+
platform = (int)Target.CorDebugPlatform.CORDB_PLATFORM_WINDOWS_X86;
135+
break;
136+
case 0x8664: // IMAGE_FILE_MACHINE_AMD64
137+
platform = (int)Target.CorDebugPlatform.CORDB_PLATFORM_WINDOWS_AMD64;
138+
break;
139+
case 0x01c4: // IMAGE_FILE_MACHINE_ARMNT
140+
platform = (int)Target.CorDebugPlatform.CORDB_PLATFORM_WINDOWS_ARM;
141+
break;
142+
case 0xAA64: // IMAGE_FILE_MACHINE_ARM64
143+
platform = (int)Target.CorDebugPlatform.CORDB_PLATFORM_WINDOWS_ARM64;
144+
break;
145+
}
146+
return hr;
147+
},
148+
out ContractDescriptorTarget? target))
149+
{
150+
return -1;
151+
}
152+
153+
Legacy.SOSDacImpl impl = new(target, null);
154+
nint ccw = cw.GetOrCreateComInterfaceForObject(impl, CreateComInterfaceFlags.None);
155+
Marshal.QueryInterface(ccw, *pIID, out nint ptrToIface);
156+
*iface = (void*)ptrToIface;
157+
158+
// Decrement reference count on ccw because QI increments it
159+
Marshal.Release(ccw);
160+
161+
return 0;
162+
}
86163
}

src/native/managed/cdacreader/src/Legacy/ICLRData.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,49 @@ internal unsafe partial interface ICLRDataEnumMemoryRegions
1717
[PreserveSig]
1818
int EnumMemoryRegions(/*ICLRDataEnumMemoryRegionsCallback*/ void* callback, uint miniDumpFlags, /*CLRDataEnumMemoryFlags*/ int clrFlags);
1919
}
20+
21+
[GeneratedComInterface]
22+
[Guid("3e11ccee-d08b-43e5-af01-32717a64da03")]
23+
internal unsafe partial interface ICLRDataTarget
24+
{
25+
[PreserveSig]
26+
int GetMachineType(uint* machineType);
27+
28+
[PreserveSig]
29+
int GetPointerSize(uint* pointerSize);
30+
31+
[PreserveSig]
32+
int GetImageBase([MarshalAs(UnmanagedType.LPWStr)] string imagePath, ulong* baseAddress);
33+
34+
[PreserveSig]
35+
int ReadVirtual(ulong address, byte* buffer, uint bytesRequested, uint* bytesRead);
36+
37+
[PreserveSig]
38+
int WriteVirtual(ulong address, byte* buffer, uint bytesRequested, uint* bytesWritten);
39+
40+
[PreserveSig]
41+
int GetTLSValue(uint threadID, uint index, ulong* value);
42+
43+
[PreserveSig]
44+
int SetTLSValue(uint threadID, uint index, ulong value);
45+
46+
[PreserveSig]
47+
int GetCurrentThreadID(uint* threadID);
48+
49+
[PreserveSig]
50+
int GetThreadContext(uint threadID, uint contextFlags, uint contextSize, byte* context);
51+
52+
[PreserveSig]
53+
int SetThreadContext(uint threadID, uint contextSize, byte* context);
54+
55+
[PreserveSig]
56+
int Request(uint reqCode, uint inBufferSize, byte* inBuffer, uint outBufferSize, byte* outBuffer);
57+
}
58+
59+
[GeneratedComInterface]
60+
[Guid("17d5b8c6-34a9-407f-af4f-a930201d4e02")]
61+
internal unsafe partial interface ICLRContractLocator
62+
{
63+
[PreserveSig]
64+
int GetContractDescriptor(ulong* contractAddress);
65+
}

src/tools/StressLogAnalyzer/src/Program.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,6 @@ ContractDescriptorTarget CreateTarget() => ContractDescriptorTarget.Create(
493493
[TargetPointer.Null, new TargetPointer(header->memoryBase + (nuint)((byte*)&header->moduleTable - (byte*)header))],
494494
(address, buffer) => ReadFromMemoryMappedLog(address, buffer, header),
495495
(threadId, contextFlags, contextSize, bufferToFill) => throw new NotImplementedException("StressLogAnalyzer does not provide GetTargetThreadContext implementation"),
496-
(out platform) => throw new NotImplementedException("StressLogAnalyzer does not provide GetTargetPlatform implementation"),
497496
true,
498497
nuint.Size);
499498
}

0 commit comments

Comments
 (0)