From 6b7f5a0211e971308e1325a3ae07e73990551eee Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Wed, 3 Nov 2021 15:41:21 -0700 Subject: [PATCH 1/6] Add System.Diagnostics.StackFrame.GetMethodInfoFromNativeIP API for VS4Mac Issue: https://github.com/dotnet/runtime/issues/61186 --- .../System/Diagnostics/StackFrame.CoreCLR.cs | 21 +++++++++++++++++++ src/coreclr/vm/debugdebugger.cpp | 20 +++++++++++++++++- src/coreclr/vm/debugdebugger.h | 2 ++ src/coreclr/vm/qcallentrypoints.cpp | 1 + .../src/ILLink/ILLink.Descriptors.Shared.xml | 3 +++ 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs index 948ebd2537230..2e22f10c7568c 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs @@ -2,6 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Text; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace System.Diagnostics { @@ -50,5 +53,23 @@ private void BuildStackFrame(int skipFrames, bool needFileInfo) } private static bool AppendStackFrameWithoutMethodBase(StringBuilder sb) => false; + + [DllImport(RuntimeHelpers.QCall, EntryPoint = "StackFrame_GetMethodDescFromNativeIP")] + private static extern RuntimeMethodHandleInternal GetMethodDescFromNativeIP(IntPtr ip); + + /// + /// Returns the method info instance for the managed code IP address. + /// + /// code address + /// MethodInfo instance or null if IP not found + internal static MethodInfo? GetMethodInfoFromNativeIP(IntPtr ip) + { + RuntimeMethodHandleInternal method = GetMethodDescFromNativeIP(ip); + + if (method.Value == IntPtr.Zero) + return null; + + return RuntimeType.GetMethodBase(null, method) as MethodInfo; + } } } diff --git a/src/coreclr/vm/debugdebugger.cpp b/src/coreclr/vm/debugdebugger.cpp index fa55f3ed2c2c7..000b399b6301a 100644 --- a/src/coreclr/vm/debugdebugger.cpp +++ b/src/coreclr/vm/debugdebugger.cpp @@ -297,7 +297,6 @@ FCIMPL0(FC_BOOL_RET, DebugDebugger::IsLogging) } FCIMPLEND - FCIMPL4(void, DebugStackTrace::GetStackFramesInternal, StackFrameHelper* pStackFrameHelperUNSAFE, INT32 iSkip, @@ -778,6 +777,25 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal, } FCIMPLEND +extern MethodDesc* QCALLTYPE StackFrame_GetMethodDescFromNativeIP(LPVOID ip) +{ + QCALL_CONTRACT; + + MethodDesc* pResult = nullptr; + + BEGIN_QCALL; + + EECodeInfo codeInfo((PCODE)ip); + if (codeInfo.IsValid()) + { + pResult = codeInfo.GetMethodDesc(); + } + + END_QCALL; + + return pResult; +} + FORCEINLINE void HolderDestroyStrongHandle(OBJECTHANDLE h) { if (h != NULL) DestroyStrongHandle(h); } typedef Wrapper, HolderDestroyStrongHandle, NULL> StrongHandleHolder; diff --git a/src/coreclr/vm/debugdebugger.h b/src/coreclr/vm/debugdebugger.h index 3c9fd17cc4357..b559531524336 100644 --- a/src/coreclr/vm/debugdebugger.h +++ b/src/coreclr/vm/debugdebugger.h @@ -171,4 +171,6 @@ class DebugStackTrace }; +extern "C" MethodDesc* QCALLTYPE StackFrame_GetMethodDescFromNativeIP(LPVOID ip); + #endif // __DEBUG_DEBUGGER_h__ diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 22327cdc79c80..472a2c1a962c6 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -115,6 +115,7 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeModule_GetType) DllImportEntry(RuntimeModule_GetScopeName) DllImportEntry(RuntimeModule_GetFullyQualifiedName) + DllImportEntry(StackFrame_GetMethodDescFromNativeIP) DllImportEntry(ModuleBuilder_GetStringConstant) DllImportEntry(ModuleBuilder_GetTypeRef) DllImportEntry(ModuleBuilder_GetTokenFromTypeSpec) diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml index 0618f1644ea32..5c313e6905478 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml @@ -60,6 +60,9 @@ + + + From dbe2368c14669a8b09d1bcaaabd5759b631e79a2 Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Sun, 7 Nov 2021 09:40:02 -0800 Subject: [PATCH 2/6] Code review feedback. Return MethodBase instead of MethodInfo. Rename to GetMethodFromNativeIP. --- .../src/System/Diagnostics/StackFrame.CoreCLR.cs | 6 +++--- src/coreclr/vm/debugdebugger.cpp | 3 +++ .../src/ILLink/ILLink.Descriptors.Shared.xml | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs index 2e22f10c7568c..b081554686ffd 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs @@ -61,15 +61,15 @@ private void BuildStackFrame(int skipFrames, bool needFileInfo) /// Returns the method info instance for the managed code IP address. /// /// code address - /// MethodInfo instance or null if IP not found - internal static MethodInfo? GetMethodInfoFromNativeIP(IntPtr ip) + /// MethodBase instance for the method or null if IP not found + internal static MethodBase? GetMethodFromNativeIP(IntPtr ip) { RuntimeMethodHandleInternal method = GetMethodDescFromNativeIP(ip); if (method.Value == IntPtr.Zero) return null; - return RuntimeType.GetMethodBase(null, method) as MethodInfo; + return RuntimeType.GetMethodBase(null, method); } } } diff --git a/src/coreclr/vm/debugdebugger.cpp b/src/coreclr/vm/debugdebugger.cpp index 000b399b6301a..2ade537044abb 100644 --- a/src/coreclr/vm/debugdebugger.cpp +++ b/src/coreclr/vm/debugdebugger.cpp @@ -785,6 +785,9 @@ extern MethodDesc* QCALLTYPE StackFrame_GetMethodDescFromNativeIP(LPVOID ip) BEGIN_QCALL; + // TODO: There is a race for dynamic and collectible methods here between getting + // the MethodDesc here and when the managed wrapper converts it into a MethodBase + // where the method could be collected. EECodeInfo codeInfo((PCODE)ip); if (codeInfo.IsValid()) { diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml index 5c313e6905478..de690e6b9b28d 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml @@ -61,7 +61,7 @@ - + From 9a14e5d6eb55a3dafd9e8ca82ca6f0a2d3773316 Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Sun, 7 Nov 2021 10:29:58 -0800 Subject: [PATCH 3/6] Fix Mono build break --- .../src/System/Diagnostics/StackFrame.Mono.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mono/System.Private.CoreLib/src/System/Diagnostics/StackFrame.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Diagnostics/StackFrame.Mono.cs index c4d73bb865da0..b882ddbb38b05 100644 --- a/src/mono/System.Private.CoreLib/src/System/Diagnostics/StackFrame.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Diagnostics/StackFrame.Mono.cs @@ -51,5 +51,11 @@ private void BuildStackFrame(int skipFrames, bool needFileInfo) private static extern bool get_frame_info(int skipFrames, bool needFileInfo, out MethodBase method, out int ilOffset, out int nativeOffset, out string file, out int line, out int column); + /// + /// Returns the method info instance for the managed code IP address. + /// + /// code address + /// MethodBase instance for the method or null if IP not found + internal static MethodBase? GetMethodFromNativeIP(IntPtr ip) => throw new NotSupportedException(); } } From b3a9a6086dcef769b82a5750489738254b6aee80 Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Sun, 7 Nov 2021 11:01:08 -0800 Subject: [PATCH 4/6] Better fix for Mono break --- .../src/ILLink/ILLink.Descriptors.Shared.xml | 4 ++++ .../src/ILLink/ILLink.Descriptors.Shared.xml | 3 --- .../src/System/Diagnostics/StackFrame.Mono.cs | 6 ------ 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml b/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml index 1b4e3a1bd2acd..d57d05bc00ff8 100644 --- a/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml +++ b/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml @@ -28,6 +28,10 @@ + + + + diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml index de690e6b9b28d..0618f1644ea32 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml @@ -60,9 +60,6 @@ - - - diff --git a/src/mono/System.Private.CoreLib/src/System/Diagnostics/StackFrame.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Diagnostics/StackFrame.Mono.cs index b882ddbb38b05..c4d73bb865da0 100644 --- a/src/mono/System.Private.CoreLib/src/System/Diagnostics/StackFrame.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Diagnostics/StackFrame.Mono.cs @@ -51,11 +51,5 @@ private void BuildStackFrame(int skipFrames, bool needFileInfo) private static extern bool get_frame_info(int skipFrames, bool needFileInfo, out MethodBase method, out int ilOffset, out int nativeOffset, out string file, out int line, out int column); - /// - /// Returns the method info instance for the managed code IP address. - /// - /// code address - /// MethodBase instance for the method or null if IP not found - internal static MethodBase? GetMethodFromNativeIP(IntPtr ip) => throw new NotSupportedException(); } } From 3aeaed646f2cfa1cdde31b03dd971604047e61cc Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Mon, 8 Nov 2021 19:34:57 -0800 Subject: [PATCH 5/6] Code review feedback --- .../src/ILLink/ILLink.Descriptors.Shared.xml | 3 --- .../src/System/Diagnostics/StackFrame.CoreCLR.cs | 4 +++- .../src/ILLink/ILLink.Descriptors.LibraryBuild.xml | 4 ++++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml b/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml index d57d05bc00ff8..e003b333b127c 100644 --- a/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml +++ b/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml @@ -29,9 +29,6 @@ - - - diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs index b081554686ffd..7863cb00d23f1 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs @@ -58,7 +58,9 @@ private void BuildStackFrame(int skipFrames, bool needFileInfo) private static extern RuntimeMethodHandleInternal GetMethodDescFromNativeIP(IntPtr ip); /// - /// Returns the method info instance for the managed code IP address. + /// Returns the MethodBase instance for the managed code IP address. + /// + /// Warning: The implementation of this method has race for dynamic and collectible methods. /// /// code address /// MethodBase instance for the method or null if IP not found diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.LibraryBuild.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.LibraryBuild.xml index 53a41aff8c935..ee28b6e38cfe6 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.LibraryBuild.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.LibraryBuild.xml @@ -4,5 +4,9 @@ + + + + From 308f640f4f4bad6faea149fd7baf35b274b7cd63 Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Tue, 9 Nov 2021 08:28:31 -0800 Subject: [PATCH 6/6] Remove unneccesary blank line --- .../src/ILLink/ILLink.Descriptors.Shared.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml b/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml index e003b333b127c..1b4e3a1bd2acd 100644 --- a/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml +++ b/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml @@ -28,7 +28,6 @@ -