diff --git a/src/coreclr/inc/sospriv.idl b/src/coreclr/inc/sospriv.idl index 9e8f422e438783..f56be4132f1e47 100644 --- a/src/coreclr/inc/sospriv.idl +++ b/src/coreclr/inc/sospriv.idl @@ -655,4 +655,5 @@ interface ISOSDacInterface17 : IUnknown HRESULT GetStressLogThreadEnumerator([out] ISOSStressLogThreadEnum **ppEnum); HRESULT GetStressLogMessageEnumerator([in] CLRDATA_ADDRESS threadStressLogAddress, [out] ISOSStressLogMsgEnum **ppEnum); + HRESULT GetStressLogMemoryRanges([out] ISOSMemoryEnum **ppEnum); } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IStressLog.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IStressLog.cs index 4bd41735561628..89c4345f3de46c 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IStressLog.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IStressLog.cs @@ -33,6 +33,10 @@ public record struct StressMsgData( ulong Timestamp, IReadOnlyList Args); +public record struct StressLogMemoryRange( + TargetPointer Start, + ulong Size); + public interface IStressLog : IContract { static string IContract.Name { get; } = nameof(StressLog); @@ -42,6 +46,7 @@ public interface IStressLog : IContract IEnumerable GetThreadStressLogs(TargetPointer Logs) => throw new NotImplementedException(); IEnumerable GetStressMessages(ThreadStressLogData threadLog) => throw new NotImplementedException(); bool IsPointerInStressLog(StressLogData stressLog, TargetPointer pointer) => throw new NotImplementedException(); + IEnumerable GetStressLogMemoryRanges(StressLogData stressLog) => throw new NotImplementedException(); } public readonly struct StressLog : IStressLog 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 c5d0d7b82ce7cd..1e0ca2382aeb37 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 @@ -231,6 +231,16 @@ public bool IsPointerInStressLog(StressLogData stressLog, TargetPointer pointer) return false; } + public IEnumerable GetStressLogMemoryRanges(StressLogData stressLog) + { + ulong chunkSize = target.GetTypeInfo(DataType.StressLogChunk).Size!.Value; + StressLogMemory stressLogMemory = target.ProcessedData.GetOrAdd(stressLog.Logs); + foreach (TargetPointer chunk in stressLogMemory.Chunks) + { + yield return new StressLogMemoryRange(chunk, chunkSize); + } + } + private sealed class StressLogMemory(IReadOnlyList chunks) : Data.IData { public static StressLogMemory Create(Target target, TargetPointer address) @@ -343,6 +353,7 @@ internal sealed class StressLog_1(Target target) : IStressLog public IEnumerable GetThreadStressLogs(TargetPointer Logs) => traversal.GetThreadStressLogs(Logs); public IEnumerable GetStressMessages(ThreadStressLogData threadLog) => traversal.GetStressMessages(threadLog); public bool IsPointerInStressLog(StressLogData stressLog, TargetPointer pointer) => traversal.IsPointerInStressLog(stressLog, pointer); + public IEnumerable GetStressLogMemoryRanges(StressLogData stressLog) => traversal.GetStressLogMemoryRanges(stressLog); } @@ -356,4 +367,5 @@ internal sealed class StressLog_2(Target target) : IStressLog public IEnumerable GetThreadStressLogs(TargetPointer Logs) => traversal.GetThreadStressLogs(Logs); public IEnumerable GetStressMessages(ThreadStressLogData threadLog) => traversal.GetStressMessages(threadLog); public bool IsPointerInStressLog(StressLogData stressLog, TargetPointer pointer) => traversal.IsPointerInStressLog(stressLog, pointer); + public IEnumerable GetStressLogMemoryRanges(StressLogData stressLog) => traversal.GetStressLogMemoryRanges(stressLog); } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ISOSDacInterface.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ISOSDacInterface.cs index 6db49253e766bc..6cafe023802c0e 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ISOSDacInterface.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ISOSDacInterface.cs @@ -1266,4 +1266,8 @@ int GetStressLogMessageEnumerator( ClrDataAddress threadStressLogAddress, DacComNullableByRef ppEnum); + [PreserveSig] + int GetStressLogMemoryRanges( + DacComNullableByRef ppEnum); + } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs index f1b25ec8ffb198..68a99b6e5a268d 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs @@ -1745,6 +1745,12 @@ public SOSMemoryEnum(Target target, IReadOnlyList regions, I } } + public SOSMemoryEnum(SOSMemoryRegion[] regions, ISOSMemoryEnum? legacyMemoryEnum = null) + { + _regions = regions; + _legacyMemoryEnum = legacyMemoryEnum; + } + int ISOSMemoryEnum.Next(uint count, SOSMemoryRegion[] memRegions, uint* pNeeded) { int hr = HResults.S_OK; @@ -7348,5 +7354,35 @@ int ISOSDacInterface17.GetStressLogMessageEnumerator( return hr; } + int ISOSDacInterface17.GetStressLogMemoryRanges(DacComNullableByRef ppEnum) + { + int hr = HResults.S_OK; + try + { + Contracts.IStressLog stressLogContract = _target.Contracts.StressLog; + if (!stressLogContract.HasStressLog()) + return HResults.S_FALSE; + + Contracts.StressLogData logData = stressLogContract.GetStressLogData(); + + SOSMemoryRegion[] regions = stressLogContract.GetStressLogMemoryRanges(logData) + .Select(r => new SOSMemoryRegion + { + Start = r.Start.ToClrDataAddress(_target), + Size = (ClrDataAddress)r.Size, + ExtraData = default, + Heap = 0, + }) + .ToArray(); + ppEnum.Interface = new SOSMemoryEnum(regions); + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + + return hr; + } + #endregion ISOSDacInterface17 }