diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/StackFrame.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/StackFrame.NativeAot.cs index a5fc83731d7a9..540f549ead238 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/StackFrame.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/StackFrame.NativeAot.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; +using System.Reflection; using System.Runtime; using System.Runtime.CompilerServices; using System.Text; @@ -28,6 +30,40 @@ public partial class StackFrame /// private bool _needFileInfo; + /// + /// Will be true if we attempted to retrieve the associated MethodBase but couldn't. + /// + private bool _noMethodBaseAvailable; + + /// + /// Returns the method the frame is executing + /// + [RequiresUnreferencedCode("Metadata for the method might be incomplete or removed")] + public virtual MethodBase? GetMethod() + { + TryInitializeMethodBase(); + return _method; + } + + private bool TryInitializeMethodBase() + { + if (_noMethodBaseAvailable || _ipAddress == IntPtr.Zero || _ipAddress == Exception.EdiSeparator) + return false; + + if (_method != null) + return true; + + IntPtr methodStartAddress = _ipAddress - _nativeOffset; + Debug.Assert(RuntimeImports.RhFindMethodStartAddress(_ipAddress) == methodStartAddress); + DeveloperExperience.Default.TryGetMethodBase(methodStartAddress, out _method); + if (_method == null) + { + _noMethodBaseAvailable = true; + return false; + } + return true; + } + /// /// Constructs a StackFrame corresponding to a given IP address. /// @@ -55,7 +91,6 @@ private void InitializeForIpAddress(IntPtr ipAddress, bool needFileInfo) _nativeOffset = (int)((nint)_ipAddress - (nint)methodStartAddress); DeveloperExperience.Default.TryGetILOffsetWithinMethod(_ipAddress, out _ilOffset); - DeveloperExperience.Default.TryGetMethodBase(methodStartAddress, out _method); if (needFileInfo) { @@ -98,7 +133,7 @@ internal IntPtr GetNativeIPAddress() /// internal bool HasMethod() { - return _method != null; + return TryInitializeMethodBase(); } /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrame.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrame.cs index 0b2724bb6c499..c7aeae27684bd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrame.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrame.cs @@ -134,6 +134,7 @@ public StackFrame(string? fileName, int lineNumber, int colNumber) internal bool IsLastFrameFromForeignExceptionStackTrace => _isLastFrameFromForeignExceptionStackTrace; +#if !NATIVEAOT /// /// Returns the method the frame is executing /// @@ -142,6 +143,7 @@ public StackFrame(string? fileName, int lineNumber, int colNumber) { return _method; } +#endif /// /// Returns the offset from the start of the native (jitted) code for the