From 1d67df778998c0ea7b3c8a329c9be989ccd3b17d Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Sun, 7 Nov 2021 14:48:59 -0800 Subject: [PATCH 1/3] Add System.Diagnostics.StackFrame.GetMethodInfoFromNativeIP API for VS4Mac VS4Mac needs a way to symbolize managed IPs when rethrowing a native NSException from Objective C++. This is a short term API needed for the next 6.0 service release discoverable only through reflection. Issue: #61186 --- .../src/ILLink/ILLink.Descriptors.Shared.xml | 4 ++++ .../System/Diagnostics/StackFrame.CoreCLR.cs | 17 ++++++++++++++ .../System/Diagnostics/StackTrace.CoreCLR.cs | 6 ++++- src/coreclr/vm/debugdebugger.cpp | 22 +++++++++++++++++++ src/coreclr/vm/debugdebugger.h | 2 ++ src/coreclr/vm/ecalllist.h | 1 + 6 files changed, 51 insertions(+), 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 4384581b1d1321..0096cf1551cea9 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 @@ -36,6 +36,10 @@ + + + + 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 948ebd2537230d..c4b976921cfdd6 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,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Text; +using System.Reflection; +using System.Runtime.CompilerServices; namespace System.Diagnostics { @@ -50,5 +52,20 @@ private void BuildStackFrame(int skipFrames, bool needFileInfo) } private static bool AppendStackFrameWithoutMethodBase(StringBuilder sb) => false; + + /// + /// 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) + { + RuntimeMethodHandleInternal method = StackTrace.GetMethodDescFromNativeIP(ip); + + if (method.Value == IntPtr.Zero) + return null; + + return RuntimeType.GetMethodBase(null, method); + } } } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackTrace.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackTrace.CoreCLR.cs index 9bef9fb72fae58..d82bbaf7e1e342 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackTrace.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackTrace.CoreCLR.cs @@ -1,8 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.CompilerServices; using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace System.Diagnostics { @@ -11,6 +12,9 @@ public partial class StackTrace [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void GetStackFramesInternal(StackFrameHelper sfh, int iSkip, bool fNeedFileInfo, Exception? e); + [DllImport(RuntimeHelpers.QCall)] + internal static extern RuntimeMethodHandleInternal GetMethodDescFromNativeIP(IntPtr ip); + internal static int CalculateFramesToSkip(StackFrameHelper StackF, int iNumFrames) { int iRetVal = 0; diff --git a/src/coreclr/vm/debugdebugger.cpp b/src/coreclr/vm/debugdebugger.cpp index e21939990405c2..f08e5107b13812 100644 --- a/src/coreclr/vm/debugdebugger.cpp +++ b/src/coreclr/vm/debugdebugger.cpp @@ -776,6 +776,28 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal, } FCIMPLEND +MethodDesc* QCALLTYPE DebugStackTrace::GetMethodDescFromNativeIP(LPVOID ip) +{ + QCALL_CONTRACT; + + MethodDesc* pResult = nullptr; + + 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()) + { + 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 cba432e3d8e5f2..2673f90717a695 100644 --- a/src/coreclr/vm/debugdebugger.h +++ b/src/coreclr/vm/debugdebugger.h @@ -158,6 +158,8 @@ class DebugStackTrace Object* pException ); + static MethodDesc* QCALLTYPE GetMethodDescFromNativeIP(LPVOID ip); + static void GetStackFramesFromException(OBJECTREF * e, GetStackFramesData *pData, PTRARRAYREF * pDynamicMethodArray = NULL); #ifndef DACCESS_COMPILE diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index c83248c00e2d0d..363ae6f6cfa7cc 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -128,6 +128,7 @@ FCFuncEnd() FCFuncStart(gDiagnosticsStackTrace) FCFuncElement("GetStackFramesInternal", DebugStackTrace::GetStackFramesInternal) + QCFuncElement("GetMethodDescFromNativeIP", DebugStackTrace::GetMethodDescFromNativeIP) FCFuncEnd() FCFuncStart(gEnvironmentFuncs) From e7354f1f044113fbeed65594b663a6e8dcf09558 Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Mon, 8 Nov 2021 19:23:21 -0800 Subject: [PATCH 2/3] 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 0096cf1551cea9..bc7c73a7773efe 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 @@ -37,9 +37,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 c4b976921cfdd6..3cfc7cc193ec1f 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 @@ -54,7 +54,9 @@ private void BuildStackFrame(int skipFrames, bool needFileInfo) private static bool AppendStackFrameWithoutMethodBase(StringBuilder sb) => false; /// - /// 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 53a41aff8c935a..ee28b6e38cfe61 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 df0f8ef0fba93a2d17fa4ff52b5fa6fc3fa04737 Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Tue, 9 Nov 2021 08:22:21 -0800 Subject: [PATCH 3/3] 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 bc7c73a7773efe..4384581b1d1321 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 @@ -36,7 +36,6 @@ -