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