diff --git a/docs/design/datacontracts/StackWalk.md b/docs/design/datacontracts/StackWalk.md index 99ccf0c9f7e1aa..6795924f2006b2 100644 --- a/docs/design/datacontracts/StackWalk.md +++ b/docs/design/datacontracts/StackWalk.md @@ -22,6 +22,9 @@ string GetFrameName(TargetPointer frameIdentifier); // Gets the method desc pointer associated with the given Frame. TargetPointer GetMethodDescPtr(TargetPointer framePtr); + +// Gets the method desc pointer associated with a given IStackDataFrameHandle +TargetPointer GetMethodDescPtr(IStackDataFrameHandle stackDataFrameHandle); ``` ## Version 1 @@ -347,7 +350,7 @@ TargetPointer GetFrameAddress(IStackDataFrameHandle stackDataFrameHandle); string GetFrameName(TargetPointer frameIdentifier); ``` -`GetMethodDescPtr` returns the method desc pointer associated with a Frame. If not applicable, it returns TargetPointer.Null. +`GetMethodDescPtr(TargetPointer framePtr)` returns the method desc pointer associated with a Frame. If not applicable, it returns TargetPointer.Null. * For FramedMethodFrame and most of its subclasses the methoddesc is accessible as a pointer field on the object (MethodDescPtr). The two exceptions are PInvokeCalliFrame (no valid method desc) and StubDispatchFrame. * StubDispatchFrame's MD may be either found on MethodDescPtr, or if this field is null, we look it up using a method table (RepresentativeMTPtr) and MT slot (RepresentativeSlot). * InlinedCallFrame also has a field from which we draw the method desc; however, we must first do some validation that the data in this field is valid. @@ -356,6 +359,14 @@ string GetFrameName(TargetPointer frameIdentifier); TargetPointer GetMethodDescPtr(TargetPointer framePtr) ``` +`GetMethodDescPtr(IStackDataFrameHandle stackDataFrameHandle)` returns the method desc pointer associated with a `IStackDataFrameHandle`. Note this can either be at a capital 'F' frame or a managed frame unlike the above API which works only at capital 'F' frames. +This API is implemeted as follows: +1. Try to get the current frame address with `GetFrameAddress`. If the address is not null, return `GetMethodDescPtr()`. +2. Check if the current context IP is a managed context using the ExecutionManager contract. If it is a managed contet, use the ExecutionManager context to find the related MethodDesc and return the pointer to it. +```csharp +TargetPointer GetMethodDescPtr(IStackDataFrameHandle stackDataFrameHandle) +``` + ### x86 Specifics The x86 platform has some major differences to other platforms. In general this stems from the platform being older and not having a defined unwinding codes. Instead, to unwind managed frames, we rely on GCInfo associated with JITted code. For the unwind, we do not defer to a 'Windows like' native unwinder, instead the custom unwinder implementation was ported to managed code. diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IStackWalk.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IStackWalk.cs index 552bb3f074943b..bcddb9b7254a99 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IStackWalk.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IStackWalk.cs @@ -17,6 +17,7 @@ public interface IStackWalk : IContract TargetPointer GetFrameAddress(IStackDataFrameHandle stackDataFrameHandle) => throw new NotImplementedException(); string GetFrameName(TargetPointer frameIdentifier) => throw new NotImplementedException(); TargetPointer GetMethodDescPtr(TargetPointer framePtr) => throw new NotImplementedException(); + TargetPointer GetMethodDescPtr(IStackDataFrameHandle stackDataFrameHandle) => throw new NotImplementedException(); } public struct StackWalk : IStackWalk diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DacStreams_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DacStreams_1.cs index 8b72aaa4270a22..f933cb28a07258 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DacStreams_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DacStreams_1.cs @@ -32,10 +32,16 @@ internal DacStreams_1(Target target) public string? StringFromEEAddress(TargetPointer address) { // We use the data subsystem to handle caching results from processing this data - var dictionary = _target.ProcessedData.GetOrAdd(0).EEObjectToString; - - dictionary.TryGetValue(address, out string? result); - return result; + try + { + var dictionary = _target.ProcessedData.GetOrAdd(0).EEObjectToString; + dictionary.TryGetValue(address, out string? result); + return result; + } + catch (VirtualReadException) + { + return null; + } } internal sealed class DacStreams_1_Data : IData diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/FrameHandling/FrameIterator.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/FrameHandling/FrameIterator.cs index 46407d5fc9d14d..132df209e67256 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/FrameHandling/FrameIterator.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/FrameHandling/FrameIterator.cs @@ -187,23 +187,6 @@ private IPlatformFrameHandler GetFrameHandler(IPlatformAgnosticContext context) }; } - private static bool InlinedCallFrameHasFunction(Data.InlinedCallFrame frame, Target target) - { - if (target.PointerSize == 4) - { - return frame.Datum != TargetPointer.Null && (frame.Datum.Value & 0x1) != 0; - } - else - { - return ((long)frame.Datum.Value & ~0xffff) != 0; - } - } - - private static bool InlinedCallFrameHasActiveCall(Data.InlinedCallFrame frame) - { - return frame.CallerReturnAddress != TargetPointer.Null; - } - public static TargetPointer GetMethodDescPtr(TargetPointer framePtr, Target target) { Data.Frame frame = target.ProcessedData.GetOrAdd(framePtr); @@ -247,4 +230,21 @@ public static TargetPointer GetMethodDescPtr(TargetPointer framePtr, Target targ return TargetPointer.Null; } } + + private static bool InlinedCallFrameHasFunction(Data.InlinedCallFrame frame, Target target) + { + if (target.PointerSize == 4) + { + return frame.Datum != TargetPointer.Null && (frame.Datum.Value & 0x1) != 0; + } + else + { + return ((long)frame.Datum.Value & ~0xffff) != 0; + } + } + + private static bool InlinedCallFrameHasActiveCall(Data.InlinedCallFrame frame) + { + return frame.CallerReturnAddress != TargetPointer.Null; + } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalk_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalk_1.cs index a16188407fc28c..2aef303cc6538d 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalk_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalk_1.cs @@ -175,6 +175,27 @@ TargetPointer IStackWalk.GetFrameAddress(IStackDataFrameHandle stackDataFrameHan string IStackWalk.GetFrameName(TargetPointer frameIdentifier) => FrameIterator.GetFrameName(_target, frameIdentifier); + TargetPointer IStackWalk.GetMethodDescPtr(TargetPointer framePtr) + => FrameIterator.GetMethodDescPtr(framePtr, _target); + + TargetPointer IStackWalk.GetMethodDescPtr(IStackDataFrameHandle stackDataFrameHandle) + { + StackDataFrameHandle handle = AssertCorrectHandle(stackDataFrameHandle); + + // if we are at a capital F Frame, we can get the method desc from the frame + // TODO(cdac): Support special fReportInteropMD case https://github.com/dotnet/runtime/issues/119724 + TargetPointer framePtr = ((IStackWalk)this).GetFrameAddress(handle); + if (framePtr != TargetPointer.Null) + return ((IStackWalk)this).GetMethodDescPtr(framePtr); + + // otherwise try to get the method desc from the IP + if (!IsManaged(handle.Context.InstructionPointer, out CodeBlockHandle? codeBlockHandle)) + return TargetPointer.Null; + + IExecutionManager eman = _target.Contracts.ExecutionManager; + return eman.GetMethodDesc(codeBlockHandle.Value); + } + private bool IsManaged(TargetPointer ip, [NotNullWhen(true)] out CodeBlockHandle? codeBlockHandle) { IExecutionManager eman = _target.Contracts.ExecutionManager; @@ -205,11 +226,6 @@ private unsafe void FillContextFromThread(IPlatformAgnosticContext context, Thre context.FillFromBuffer(buffer); } - TargetPointer IStackWalk.GetMethodDescPtr(TargetPointer framePtr) - { - return FrameIterator.GetMethodDescPtr(framePtr, _target); - } - private static StackDataFrameHandle AssertCorrectHandle(IStackDataFrameHandle stackDataFrameHandle) { if (stackDataFrameHandle is not StackDataFrameHandle handle) diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataFrame.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataFrame.cs new file mode 100644 index 00000000000000..6edd3f4598f26f --- /dev/null +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataFrame.cs @@ -0,0 +1,127 @@ +// 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.Diagnostics; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; +using Microsoft.Diagnostics.DataContractReader.Contracts; + +namespace Microsoft.Diagnostics.DataContractReader.Legacy; + +[GeneratedComClass] +internal sealed unsafe partial class ClrDataFrame : IXCLRDataFrame, IXCLRDataFrame2 +{ + private readonly Target _target; + private readonly IXCLRDataFrame? _legacyImpl; + private readonly IXCLRDataFrame2? _legacyImpl2; + + private readonly IStackDataFrameHandle _dataFrame; + + public ClrDataFrame(Target target, IStackDataFrameHandle dataFrame, IXCLRDataFrame? legacyImpl) + { + _target = target; + _legacyImpl = legacyImpl; + _legacyImpl2 = legacyImpl as IXCLRDataFrame2; + + _dataFrame = dataFrame; + } + + // IXCLRDataFrame implementation + int IXCLRDataFrame.GetFrameType(uint* simpleType, uint* detailedType) + => _legacyImpl is not null ? _legacyImpl.GetFrameType(simpleType, detailedType) : HResults.E_NOTIMPL; + + int IXCLRDataFrame.GetContext( + uint contextFlags, + uint contextBufSize, + uint* contextSize, + [Out, MarshalUsing(CountElementName = nameof(contextBufSize))] byte[] contextBuf) + => _legacyImpl is not null ? _legacyImpl.GetContext(contextFlags, contextBufSize, contextSize, contextBuf) : HResults.E_NOTIMPL; + + int IXCLRDataFrame.GetAppDomain(void** appDomain) + => _legacyImpl is not null ? _legacyImpl.GetAppDomain(appDomain) : HResults.E_NOTIMPL; + + int IXCLRDataFrame.GetNumArguments(uint* numArgs) + => _legacyImpl is not null ? _legacyImpl.GetNumArguments(numArgs) : HResults.E_NOTIMPL; + + int IXCLRDataFrame.GetArgumentByIndex( + uint index, + void** arg, + uint bufLen, + uint* nameLen, + char* name) + => _legacyImpl is not null ? _legacyImpl.GetArgumentByIndex(index, arg, bufLen, nameLen, name) : HResults.E_NOTIMPL; + + int IXCLRDataFrame.GetNumLocalVariables(uint* numLocals) + => _legacyImpl is not null ? _legacyImpl.GetNumLocalVariables(numLocals) : HResults.E_NOTIMPL; + + int IXCLRDataFrame.GetLocalVariableByIndex( + uint index, + void** localVariable, + uint bufLen, + uint* nameLen, + char* name) + => _legacyImpl is not null ? _legacyImpl.GetLocalVariableByIndex(index, localVariable, bufLen, nameLen, name) : HResults.E_NOTIMPL; + + int IXCLRDataFrame.GetCodeName( + uint flags, + uint bufLen, + uint* nameLen, + char* nameBuf) + => _legacyImpl is not null ? _legacyImpl.GetCodeName(flags, bufLen, nameLen, nameBuf) : HResults.E_NOTIMPL; + + int IXCLRDataFrame.GetMethodInstance(out IXCLRDataMethodInstance? method) + { + int hr = HResults.S_OK; + method = null; + + IXCLRDataMethodInstance? legacyMethod = null; + if (_legacyImpl is not null) + { + int hrLocal = _legacyImpl.GetMethodInstance(out legacyMethod); + if (hrLocal < 0) + return hrLocal; + } + + try + { + IStackWalk stackWalk = _target.Contracts.StackWalk; + IRuntimeTypeSystem rts = _target.Contracts.RuntimeTypeSystem; + + TargetPointer methodDesc = stackWalk.GetMethodDescPtr(_dataFrame); + + if (methodDesc == TargetPointer.Null) + throw Marshal.GetExceptionForHR(/*E_NOINTERFACE*/ HResults.COR_E_INVALIDCAST)!; + + MethodDescHandle mdh = rts.GetMethodDescHandle(methodDesc); + TargetPointer appDomain = _target.ReadPointer( + _target.ReadGlobalPointer(Constants.Globals.AppDomain)); + + method = new ClrDataMethodInstance(_target, mdh, appDomain, legacyMethod); + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + + return hr; + } + + int IXCLRDataFrame.Request( + uint reqCode, + uint inBufferSize, + byte* inBuffer, + uint outBufferSize, + byte* outBuffer) + => _legacyImpl is not null ? _legacyImpl.Request(reqCode, inBufferSize, inBuffer, outBufferSize, outBuffer) : HResults.E_NOTIMPL; + + int IXCLRDataFrame.GetNumTypeArguments(uint* numTypeArgs) + => _legacyImpl is not null ? _legacyImpl.GetNumTypeArguments(numTypeArgs) : HResults.E_NOTIMPL; + + int IXCLRDataFrame.GetTypeArgumentByIndex(uint index, void** typeArg) + => _legacyImpl is not null ? _legacyImpl.GetTypeArgumentByIndex(index, typeArg) : HResults.E_NOTIMPL; + + // IXCLRDataFrame2 implementation + int IXCLRDataFrame2.GetExactGenericArgsToken(void** genericToken) + => _legacyImpl2 is not null ? _legacyImpl2.GetExactGenericArgsToken(genericToken) : HResults.E_NOTIMPL; +} diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataMethodInstance.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataMethodInstance.cs index 2661e257853557..ad2930e770093a 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataMethodInstance.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataMethodInstance.cs @@ -9,6 +9,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; +using System.Text; using Microsoft.Diagnostics.DataContractReader.Contracts; namespace Microsoft.Diagnostics.DataContractReader.Legacy; @@ -110,7 +111,82 @@ int IXCLRDataMethodInstance.GetTokenAndScope(uint* token, void** /*IXCLRDataModu } int IXCLRDataMethodInstance.GetName(uint flags, uint bufLen, uint* nameLen, char* nameBuf) - => _legacyImpl is not null ? _legacyImpl.GetName(flags, bufLen, nameLen, nameBuf) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + + try + { + IRuntimeTypeSystem rts = _target.Contracts.RuntimeTypeSystem; + + if (flags != 0) + throw new ArgumentException(); + + bool fallbackToUnknown = false; + StringBuilder sb = new(); + try + { + TypeNameBuilder.AppendMethodInternal( + _target, + sb, + _methodDesc, + TypeNameFormat.FormatSignature | + TypeNameFormat.FormatNamespace | + TypeNameFormat.FormatFullInst); + } + catch + { + string? fallbackName = _target.Contracts.DacStreams.StringFromEEAddress(_methodDesc.Address); + if (fallbackName != null) + { + sb.Clear(); + sb.Append(fallbackName); + } + else + { + sb.Clear(); + sb.Append("Unknown"); + fallbackToUnknown = true; + } + } + + OutputBufferHelpers.CopyStringToBuffer(nameBuf, bufLen, nameLen, sb.ToString()); + + if (!fallbackToUnknown && nameBuf != null && bufLen < sb.Length + 1) + { + hr = HResults.S_FALSE; + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + +#if DEBUG + if (_legacyImpl is not null) + { + uint nameLenLocal = 0; + char[] nameBufLocal = new char[bufLen > 0 ? bufLen : 1]; + int hrLocal; + fixed (char* pNameBufLocal = nameBufLocal) + { + hrLocal = _legacyImpl.GetName(flags, bufLen, &nameLenLocal, nameBuf is null ? null : pNameBufLocal); + } + + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (nameLen is not null) + Debug.Assert(nameLenLocal == *nameLen, $"cDAC: {*nameLen:x}, DAC: {nameLenLocal:x}"); + + if (nameBuf is not null) + { + string dacName = new string(nameBufLocal, 0, (int)nameLenLocal - 1); + string cdacName = new string(nameBuf); + Debug.Assert(dacName == cdacName, $"cDAC: {cdacName}, DAC: {dacName}"); + } + } +#endif + + return hr; + } int IXCLRDataMethodInstance.GetFlags(uint* flags) => _legacyImpl is not null ? _legacyImpl.GetFlags(flags) : HResults.E_NOTIMPL; diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataStackWalk.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataStackWalk.cs index 720d445fc3f2d4..0448ec77295953 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataStackWalk.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataStackWalk.cs @@ -84,8 +84,33 @@ int IXCLRDataStackWalk.GetContext(uint contextFlags, uint contextBufSize, uint* return hr; } - int IXCLRDataStackWalk.GetFrame(void** frame) - => _legacyImpl is not null ? _legacyImpl.GetFrame(frame) : HResults.E_NOTIMPL; + int IXCLRDataStackWalk.GetFrame(out IXCLRDataFrame? frame) + { + int hr = HResults.S_OK; + frame = default; + + IXCLRDataFrame? legacyFrame = null; + if (_legacyImpl is not null) + { + int hrLocal = _legacyImpl.GetFrame(out legacyFrame); + if (hrLocal < 0) + return hrLocal; + } + + try + { + if (!_currentFrameIsValid) + throw new ArgumentException(); + + frame = new ClrDataFrame(_target, _dataFrames.Current, legacyFrame); + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + + return hr; + } int IXCLRDataStackWalk.GetFrameType(uint* simpleType, uint* detailedType) => _legacyImpl is not null ? _legacyImpl.GetFrameType(simpleType, detailedType) : HResults.E_NOTIMPL; int IXCLRDataStackWalk.GetStackSizeSkipped(ulong* stackSizeSkipped) diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/IXCLRData.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/IXCLRData.cs index 0977ecc053845d..d304d80aa6dfaf 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/IXCLRData.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/IXCLRData.cs @@ -339,6 +339,7 @@ int GetContext( uint contextBufSize, uint* contextSize, [Out, MarshalUsing(CountElementName = nameof(contextBufSize))] byte[] contextBuf); + [PreserveSig] int SetContext(uint contextSize, [In, MarshalUsing(CountElementName = nameof(contextSize))] byte[] context); @@ -350,8 +351,9 @@ int GetContext( [PreserveSig] int GetFrameType(/*CLRDataSimpleFrameType*/ uint* simpleType, /*CLRDataDetailedFrameType*/ uint* detailedType); + [PreserveSig] - int GetFrame(/*IXCLRDataFrame*/ void** frame); + int GetFrame(out IXCLRDataFrame? frame); [PreserveSig] int Request(uint reqCode, uint inBufferSize, byte* inBuffer, uint outBufferSize, byte* outBuffer); @@ -360,6 +362,78 @@ int GetContext( int SetContext2(uint flags, uint contextSize, [In, MarshalUsing(CountElementName = nameof(contextSize))] byte[] context); } +[GeneratedComInterface] +[Guid("271498C2-4085-4766-BC3A-7F8ED188A173")] +internal unsafe partial interface IXCLRDataFrame +{ + [PreserveSig] + int GetFrameType(uint* simpleType, uint* detailedType); + + [PreserveSig] + int GetContext( + uint contextFlags, + uint contextBufSize, + uint* contextSize, + [Out, MarshalUsing(CountElementName = nameof(contextBufSize))] byte[] contextBuf); + + [PreserveSig] + int GetAppDomain(/*IXCLRDataAppDomain*/ void** appDomain); + + [PreserveSig] + int GetNumArguments(uint* numArgs); + + [PreserveSig] + int GetArgumentByIndex( + uint index, + /*IXCLRDataValue*/ void** arg, + uint bufLen, + uint* nameLen, + char* name); + + [PreserveSig] + int GetNumLocalVariables(uint* numLocals); + + [PreserveSig] + int GetLocalVariableByIndex( + uint index, + /*IXCLRDataValue*/ void** localVariable, + uint bufLen, + uint* nameLen, + char* name); + + [PreserveSig] + int GetCodeName( + uint flags, + uint bufLen, + uint* nameLen, + char* nameBuf); + + [PreserveSig] + int GetMethodInstance(out IXCLRDataMethodInstance? method); + + [PreserveSig] + int Request( + uint reqCode, + uint inBufferSize, + byte* inBuffer, + uint outBufferSize, + byte* outBuffer); + + [PreserveSig] + int GetNumTypeArguments(uint* numTypeArgs); + + [PreserveSig] + int GetTypeArgumentByIndex(uint index, /*IXCLRDataTypeInstance*/ void** typeArg); +} + +[GeneratedComInterface] +[Guid("1C4D9A4B-702D-4CF6-B290-1DB6F43050D0")] +internal unsafe partial interface IXCLRDataFrame2 +{ + [PreserveSig] + int GetExactGenericArgsToken(/*IXCLRDataValue*/ void** genericToken); +} + [GeneratedComInterface] [Guid("A5B0BEEA-EC62-4618-8012-A24FFC23934C")] internal unsafe partial interface IXCLRDataTask diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs index 821394b257cab1..fe2de6d50ae9e3 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs @@ -2047,17 +2047,12 @@ int ISOSDacInterface.GetMethodTableName(ClrDataAddress mt, uint count, char* mtN } catch { - try + string? fallbackName = _target.Contracts.DacStreams.StringFromEEAddress(mt.ToTargetPointer(_target)); + if (fallbackName != null) { - string? fallbackName = _target.Contracts.DacStreams.StringFromEEAddress(mt.ToTargetPointer(_target)); - if (fallbackName != null) - { - methodTableName.Clear(); - methodTableName.Append(fallbackName); - } + methodTableName.Clear(); + methodTableName.Append(fallbackName); } - catch - { } } OutputBufferHelpers.CopyStringToBuffer(mtName, count, pNeeded, methodTableName.ToString()); }