From 83779a46fec1e429e4f8156fd873478ae2fbb4d8 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Fri, 13 Dec 2024 12:09:33 -0800 Subject: [PATCH] [cdac] Clear cached data as part of IXCLRDataProcess::Flush --- .../Target.cs | 4 ++++ .../ContractDescriptorTarget.cs | 5 +++++ .../src/Legacy/SOSDacImpl.IXCLRDataProcess.cs | 10 +++++++++- .../cdacreader/tests/TestPlaceholderTarget.cs | 19 ++++++++++--------- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Target.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Target.cs index 26ff88bdacc09..aa1174cd0b2e1 100644 --- a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Target.cs +++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Target.cs @@ -139,6 +139,10 @@ public interface IDataCache /// On return, set to the cached data value, or null if the data hasn't been cached yet. /// True if a copy of the data is cached, or false otherwise bool TryGet(ulong address, [NotNullWhen(true)] out T? data); + /// + /// Clear all cached data + /// + void Clear(); } /// diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs index 965c0a1507aec..668c9c988d1d4 100644 --- a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs +++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs @@ -519,6 +519,11 @@ public bool TryGet(ulong address, [NotNullWhen(true)] out T? data) return false; } + + public void Clear() + { + _readDataByAddress.Clear(); + } } private readonly struct Reader(ReadFromTargetDelegate readFromTarget) diff --git a/src/native/managed/cdacreader/src/Legacy/SOSDacImpl.IXCLRDataProcess.cs b/src/native/managed/cdacreader/src/Legacy/SOSDacImpl.IXCLRDataProcess.cs index 58799a26cf645..f04d39aa8000a 100644 --- a/src/native/managed/cdacreader/src/Legacy/SOSDacImpl.IXCLRDataProcess.cs +++ b/src/native/managed/cdacreader/src/Legacy/SOSDacImpl.IXCLRDataProcess.cs @@ -14,7 +14,15 @@ namespace Microsoft.Diagnostics.DataContractReader.Legacy; internal sealed unsafe partial class SOSDacImpl : IXCLRDataProcess, IXCLRDataProcess2 { int IXCLRDataProcess.Flush() - => _legacyProcess is not null ? _legacyProcess.Flush() : HResults.E_NOTIMPL; + { + _target.ProcessedData.Clear(); + + // As long as any part of cDAC falls back to the legacy DAC, we need to propagate the Flush call + if (_legacyProcess is not null) + return _legacyProcess.Flush(); + + return HResults.S_OK; + } int IXCLRDataProcess.StartEnumTasks(ulong* handle) => _legacyProcess is not null ? _legacyProcess.StartEnumTasks(handle) : HResults.E_NOTIMPL; diff --git a/src/native/managed/cdacreader/tests/TestPlaceholderTarget.cs b/src/native/managed/cdacreader/tests/TestPlaceholderTarget.cs index 843266f69f370..007574ca7d743 100644 --- a/src/native/managed/cdacreader/tests/TestPlaceholderTarget.cs +++ b/src/native/managed/cdacreader/tests/TestPlaceholderTarget.cs @@ -230,19 +230,17 @@ public override Target.TypeInfo GetTypeInfo(DataType dataType) public override ContractRegistry Contracts => _contractRegistry; // A data cache that stores data in a dictionary and calls IData.Create to construct the data. - private class DefaultDataCache : Target.IDataCache + private sealed class DefaultDataCache : Target.IDataCache { - protected readonly Target _target; - protected readonly Dictionary<(ulong, Type), object?> _readDataByAddress = []; + private readonly Target _target; + private readonly Dictionary<(ulong, Type), object?> _readDataByAddress = []; public DefaultDataCache(Target target) { _target = target; } - public virtual T GetOrAdd(TargetPointer address) where T : Data.IData => DefaultGetOrAdd(address); - - protected T DefaultGetOrAdd(TargetPointer address) where T : Data.IData + public T GetOrAdd(TargetPointer address) where T : Data.IData { if (TryGet(address, out T? result)) return result; @@ -258,9 +256,7 @@ protected T DefaultGetOrAdd(TargetPointer address) where T : Data.IData return result!; } - public virtual bool TryGet(ulong address, [NotNullWhen(true)] out T? data) => DefaultTryGet(address, out data); - - protected bool DefaultTryGet(ulong address, [NotNullWhen(true)] out T? data) + public bool TryGet(ulong address, [NotNullWhen(true)] out T? data) { data = default; if (!_readDataByAddress.TryGetValue((address, typeof(T)), out object? dataObj)) @@ -273,6 +269,11 @@ protected bool DefaultTryGet(ulong address, [NotNullWhen(true)] out T? data) } return false; } + + public void Clear() + { + _readDataByAddress.Clear(); + } } }