|
1 | 1 | // Licensed to the .NET Foundation under one or more agreements.
|
2 | 2 | // The .NET Foundation licenses this file to you under the MIT license.
|
3 | 3 |
|
| 4 | +using System.Diagnostics.CodeAnalysis; |
| 5 | +using System.Reflection; |
4 | 6 | using System.Runtime;
|
5 | 7 | using System.Runtime.CompilerServices;
|
6 | 8 | using System.Text;
|
@@ -28,6 +30,40 @@ public partial class StackFrame
|
28 | 30 | /// </summary>
|
29 | 31 | private bool _needFileInfo;
|
30 | 32 |
|
| 33 | + /// <summary> |
| 34 | + /// Will be true if we attempted to retrieve the associated MethodBase but couldn't. |
| 35 | + /// </summary> |
| 36 | + private bool _noMethodBaseAvailable; |
| 37 | + |
| 38 | + /// <summary> |
| 39 | + /// Returns the method the frame is executing |
| 40 | + /// </summary> |
| 41 | + [RequiresUnreferencedCode("Metadata for the method might be incomplete or removed")] |
| 42 | + public virtual MethodBase? GetMethod() |
| 43 | + { |
| 44 | + TryInitializeMethodBase(); |
| 45 | + return _method; |
| 46 | + } |
| 47 | + |
| 48 | + private bool TryInitializeMethodBase() |
| 49 | + { |
| 50 | + if (_noMethodBaseAvailable || _ipAddress == IntPtr.Zero || _ipAddress == Exception.EdiSeparator) |
| 51 | + return false; |
| 52 | + |
| 53 | + if (_method != null) |
| 54 | + return true; |
| 55 | + |
| 56 | + IntPtr methodStartAddress = _ipAddress - _nativeOffset; |
| 57 | + Debug.Assert(RuntimeImports.RhFindMethodStartAddress(_ipAddress) == methodStartAddress); |
| 58 | + DeveloperExperience.Default.TryGetMethodBase(methodStartAddress, out _method); |
| 59 | + if (_method == null) |
| 60 | + { |
| 61 | + _noMethodBaseAvailable = true; |
| 62 | + return false; |
| 63 | + } |
| 64 | + return true; |
| 65 | + } |
| 66 | + |
31 | 67 | /// <summary>
|
32 | 68 | /// Constructs a StackFrame corresponding to a given IP address.
|
33 | 69 | /// </summary>
|
@@ -55,7 +91,6 @@ private void InitializeForIpAddress(IntPtr ipAddress, bool needFileInfo)
|
55 | 91 | _nativeOffset = (int)((nint)_ipAddress - (nint)methodStartAddress);
|
56 | 92 |
|
57 | 93 | DeveloperExperience.Default.TryGetILOffsetWithinMethod(_ipAddress, out _ilOffset);
|
58 |
| - DeveloperExperience.Default.TryGetMethodBase(methodStartAddress, out _method); |
59 | 94 |
|
60 | 95 | if (needFileInfo)
|
61 | 96 | {
|
@@ -98,7 +133,7 @@ internal IntPtr GetNativeIPAddress()
|
98 | 133 | /// </summary>
|
99 | 134 | internal bool HasMethod()
|
100 | 135 | {
|
101 |
| - return _method != null; |
| 136 | + return TryInitializeMethodBase(); |
102 | 137 | }
|
103 | 138 |
|
104 | 139 | /// <summary>
|
|
0 commit comments