diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs
index 9a51c47cb020e0..576c1fe696be55 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs
@@ -11,15 +11,15 @@ namespace System.Diagnostics
{
public static partial class Debugger
{
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "DebugDebugger_Break")]
+ private static partial void BreakInternal();
+
// Break causes a breakpoint to be signalled to an attached debugger. If no debugger
// is attached, the user is asked if they want to attach a debugger. If yes, then the
// debugger is launched.
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Break() => BreakInternal();
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void BreakInternal();
-
// Launch launches & attaches a debugger to the process. If a debugger is already attached,
// nothing happens.
//
@@ -30,11 +30,6 @@ public static partial class Debugger
// See code:NotifyOfCrossThreadDependency for more details.
private sealed class CrossThreadDependencyNotification : ICustomDebuggerNotification { }
- // Do not inline the slow path
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void NotifyOfCrossThreadDependencySlow() =>
- CustomNotification(new CrossThreadDependencyNotification());
-
// Sends a notification to the debugger to indicate that execution is about to enter a path
// involving a cross thread dependency. A debugger that has opted into this type of notification
// can take appropriate action on receipt. For example, performing a funceval normally requires
@@ -49,6 +44,14 @@ public static void NotifyOfCrossThreadDependency()
{
NotifyOfCrossThreadDependencySlow();
}
+
+ // Do not inline the slow path
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static void NotifyOfCrossThreadDependencySlow()
+ {
+ var notify = new CrossThreadDependencyNotification();
+ CustomNotification(ObjectHandleOnStack.Create(ref notify));
+ }
}
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "DebugDebugger_Launch")]
@@ -89,7 +92,7 @@ public static extern bool IsAttached
// Posts a custom notification for the attached debugger. If there is no
// debugger attached, has no effect. The debugger may or may not
// report the notification depending on its settings.
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void CustomNotification(ICustomDebuggerNotification data);
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "DebugDebugger_CustomNotification")]
+ private static partial void CustomNotification(ObjectHandleOnStack data);
}
}
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 b68e4f2884b295..8c1850d31e840b 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
@@ -30,9 +30,9 @@ internal StackFrame(StackFrameHelper stackFrameHelper, int skipFrames, bool need
private void BuildStackFrame(int skipFrames, bool needFileInfo)
{
- StackFrameHelper StackF = new StackFrameHelper(null);
+ StackFrameHelper StackF = new StackFrameHelper();
- StackF.InitializeSourceInfo(0, needFileInfo, null);
+ StackF.InitializeSourceInfo(needFileInfo, null);
int iNumOfFrames = StackF.GetNumberOfFrames();
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrameHelper.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrameHelper.cs
index 8e90b6a2eec6c6..f10af9c2347126 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrameHelper.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrameHelper.cs
@@ -13,7 +13,6 @@ namespace System.Diagnostics
// VM\DebugDebugger.h. The binder will catch some of these layout problems.
internal sealed class StackFrameHelper
{
- private Thread? targetThread;
private int[]? rgiOffset;
private int[]? rgiILOffset;
@@ -48,9 +47,8 @@ private delegate void GetSourceLineInfoDelegate(Assembly? assembly, string assem
[ThreadStatic]
private static int t_reentrancy;
- public StackFrameHelper(Thread? target)
+ public StackFrameHelper()
{
- targetThread = target;
rgMethodHandle = null;
rgiMethodToken = null;
rgiOffset = null;
@@ -85,9 +83,9 @@ public StackFrameHelper(Thread? target)
// done by GetStackFramesInternal (on Windows for old PDB format).
//
- internal void InitializeSourceInfo(int iSkip, bool fNeedFileInfo, Exception? exception)
+ internal void InitializeSourceInfo(bool fNeedFileInfo, Exception? exception)
{
- StackTrace.GetStackFramesInternal(this, iSkip, fNeedFileInfo, exception);
+ StackTrace.GetStackFramesInternal(this, fNeedFileInfo, exception);
if (!fNeedFileInfo)
return;
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 26e002f990118e..5d4bc6008e6400 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
@@ -3,13 +3,17 @@
using System.Reflection;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
namespace System.Diagnostics
{
public partial class StackTrace
{
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern void GetStackFramesInternal(StackFrameHelper sfh, int iSkip, bool fNeedFileInfo, Exception? e);
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StackTrace_GetStackFramesInternal")]
+ private static partial void GetStackFramesInternal(ObjectHandleOnStack sfh, [MarshalAs(UnmanagedType.Bool)] bool fNeedFileInfo, ObjectHandleOnStack e);
+
+ internal static void GetStackFramesInternal(StackFrameHelper sfh, bool fNeedFileInfo, Exception? e)
+ => GetStackFramesInternal(ObjectHandleOnStack.Create(ref sfh), fNeedFileInfo, ObjectHandleOnStack.Create(ref e));
internal static int CalculateFramesToSkip(StackFrameHelper StackF, int iNumFrames)
{
@@ -57,9 +61,9 @@ private void CaptureStackTrace(int skipFrames, bool fNeedFileInfo, Exception? e)
{
_methodsToSkip = skipFrames;
- StackFrameHelper StackF = new StackFrameHelper(null);
+ StackFrameHelper StackF = new StackFrameHelper();
- StackF.InitializeSourceInfo(0, fNeedFileInfo, e);
+ StackF.InitializeSourceInfo(fNeedFileInfo, e);
_numOfFrames = StackF.GetNumberOfFrames();
diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp
index 8dbd2cf2ca0588..778755481ddbff 100644
--- a/src/coreclr/debug/daccess/dacdbiimpl.cpp
+++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp
@@ -3707,7 +3707,6 @@ void DacDbiInterfaceImpl::GetStackFramesFromException(VMPTR_Object vmObject, Dac
DebugStackTrace::GetStackFramesData stackFramesData;
stackFramesData.pDomain = NULL;
- stackFramesData.skip = 0;
stackFramesData.NumFramesRequested = 0;
DebugStackTrace::GetStackFramesFromException(&objRef, &stackFramesData);
@@ -3720,7 +3719,7 @@ void DacDbiInterfaceImpl::GetStackFramesFromException(VMPTR_Object vmObject, Dac
for (INT32 index = 0; index < dacStackFramesLength; ++index)
{
- DebugStackTrace::DebugStackTraceElement const& currentElement = stackFramesData.pElements[index];
+ DebugStackTrace::Element const& currentElement = stackFramesData.pElements[index];
DacExceptionCallStackData& currentFrame = dacStackFrames[index];
AppDomain* pDomain = AppDomain::GetCurrentDomain();
diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp
index 8ed914cf310123..f2682725f0fd30 100644
--- a/src/coreclr/debug/ee/debugger.cpp
+++ b/src/coreclr/debug/ee/debugger.cpp
@@ -8849,7 +8849,7 @@ void Debugger::SendUserBreakpoint(Thread * thread)
{
THROWS;
GC_TRIGGERS;
- MODE_ANY;
+ MODE_PREEMPTIVE;
PRECONDITION(thread != NULL);
PRECONDITION(thread == ::GetThreadNULLOk());
diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc
index e29b2c75f16ac3..6e878343d3aee8 100644
--- a/src/coreclr/dlls/mscorrc/mscorrc.rc
+++ b/src/coreclr/dlls/mscorrc/mscorrc.rc
@@ -468,7 +468,6 @@ BEGIN
IDS_EE_INVALID_CA "Invalid custom attribute provided."
IDS_EE_THREAD_CANNOT_GET "Unable to retrieve thread information."
- IDS_EE_THREAD_BAD_STATE "Thread in invalid state."
IDS_EE_THREAD_ABORT_WHILE_SUSPEND "Thread is suspended; attempting to abort."
IDS_EE_NOVARIANTRETURN "PInvoke restriction: cannot return variants."
diff --git a/src/coreclr/dlls/mscorrc/resource.h b/src/coreclr/dlls/mscorrc/resource.h
index 7e9c3e9cc3fecf..3f50fc5320cb10 100644
--- a/src/coreclr/dlls/mscorrc/resource.h
+++ b/src/coreclr/dlls/mscorrc/resource.h
@@ -233,7 +233,6 @@
#define IDS_EE_INVALID_CA 0x1a10
#define IDS_EE_THREAD_CANNOT_GET 0x1a15
-#define IDS_EE_THREAD_BAD_STATE 0x1a1b
#define IDS_EE_THREAD_ABORT_WHILE_SUSPEND 0x1a1c
#define IDS_EE_NOVARIANTRETURN 0x1a1d
diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h
index 671ae48e7ee7c5..798f737786c53f 100644
--- a/src/coreclr/vm/corelib.h
+++ b/src/coreclr/vm/corelib.h
@@ -761,7 +761,6 @@ DEFINE_METHOD(SAFE_HANDLE, DISPOSE_BOOL, Dispose,
DEFINE_CLASS(SECURITY_EXCEPTION, Security, SecurityException)
DEFINE_CLASS_U(Diagnostics, StackFrameHelper, StackFrameHelper)
-DEFINE_FIELD_U(targetThread, StackFrameHelper, targetThread)
DEFINE_FIELD_U(rgiOffset, StackFrameHelper, rgiOffset)
DEFINE_FIELD_U(rgiILOffset, StackFrameHelper, rgiILOffset)
DEFINE_FIELD_U(dynamicMethods, StackFrameHelper, dynamicMethods)
diff --git a/src/coreclr/vm/debugdebugger.cpp b/src/coreclr/vm/debugdebugger.cpp
index 988818d91d53d5..abb873942abaa0 100644
--- a/src/coreclr/vm/debugdebugger.cpp
+++ b/src/coreclr/vm/debugdebugger.cpp
@@ -40,12 +40,12 @@
// Else if a native debugger is attached, this should send a native break event (kernel32!DebugBreak)
// Else, this should invoke Watson.
//
-FCIMPL0(void, DebugDebugger::Break)
+extern "C" void QCALLTYPE DebugDebugger_Break()
{
- FCALL_CONTRACT;
+ QCALL_CONTRACT;
#ifdef DEBUGGING_SUPPORTED
- HELPER_METHOD_FRAME_BEGIN_0();
+ BEGIN_QCALL;
#ifdef _DEBUG
{
@@ -73,21 +73,17 @@ FCIMPL0(void, DebugDebugger::Break)
// No managed debugger, but a native debug is attached. Explicitly fire a native user breakpoint.
// Don't rely on Watson support since that may have a different policy.
- // Toggle to preemptive before firing the debug event. This allows the debugger to suspend this
+ // Confirm we're in preemptive before firing the debug event. This allows the debugger to suspend this
// thread at the debug event.
- GCX_PREEMP();
+ _ASSERTE(!GetThread()->PreemptiveGCDisabled());
// This becomes an unmanaged breakpoint, such as int 3.
DebugBreak();
}
- else
- {
- }
- HELPER_METHOD_FRAME_END();
+ END_QCALL;
#endif // DEBUGGING_SUPPORTED
}
-FCIMPLEND
extern "C" BOOL QCALLTYPE DebugDebugger_Launch()
{
@@ -230,44 +226,146 @@ FCIMPL0(FC_BOOL_RET, DebugDebugger::IsLogging)
}
FCIMPLEND
-FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
- StackFrameHelper* pStackFrameHelperUNSAFE,
- INT32 iSkip,
- FC_BOOL_ARG fNeedFileInfo,
- Object* pExceptionUNSAFE
- )
+static StackWalkAction GetStackFramesCallback(CrawlFrame* pCf, VOID* data)
{
CONTRACTL
{
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pStackFrameHelperUNSAFE));
- PRECONDITION(CheckPointer(pExceptionUNSAFE, NULL_OK));
+ THROWS;
+ GC_TRIGGERS;
+ MODE_COOPERATIVE;
}
CONTRACTL_END;
- STACKFRAMEHELPERREF pStackFrameHelper = (STACKFRAMEHELPERREF)ObjectToOBJECTREF(pStackFrameHelperUNSAFE);
- OBJECTREF pException = ObjectToOBJECTREF(pExceptionUNSAFE);
- PTRARRAYREF dynamicMethodArrayOrig = NULL;
+ // @todo: How do we know what kind of frame we have?
+ // Can we always assume FramedMethodFrame?
+ // NOT AT ALL!!!, but we can assume it's a function
+ // because we asked the stackwalker for it!
+ MethodDesc* pFunc = pCf->GetFunction();
- HELPER_METHOD_FRAME_BEGIN_2(pStackFrameHelper, pException);
+ DebugStackTrace::GetStackFramesData* pData = (DebugStackTrace::GetStackFramesData*)data;
+ if (pData->cElements >= pData->cElementsAllocated)
+ {
+ DebugStackTrace::Element* pTemp = new (nothrow) DebugStackTrace::Element[2*pData->cElementsAllocated];
+ if (pTemp == NULL)
+ {
+ return SWA_ABORT;
+ }
- GCPROTECT_BEGIN(dynamicMethodArrayOrig);
+ memcpy(pTemp, pData->pElements, pData->cElementsAllocated * sizeof(DebugStackTrace::Element));
- ASSERT(iSkip >= 0);
+ delete [] pData->pElements;
+
+ pData->pElements = pTemp;
+ pData->cElementsAllocated *= 2;
+ }
- GetStackFramesData data;
+ PCODE ip;
+ DWORD dwNativeOffset;
- data.pDomain = GetAppDomain();
+ if (pCf->IsFrameless())
+ {
+ // Real method with jitted code.
+ dwNativeOffset = pCf->GetRelOffset();
+ ip = GetControlPC(pCf->GetRegisterSet());
+ }
+ else
+ {
+ ip = (PCODE)NULL;
+ dwNativeOffset = 0;
+ }
+
+ // Pass on to InitPass2 that the IP has already been adjusted (decremented by 1)
+ INT flags = pCf->IsIPadjusted() ? STEF_IP_ADJUSTED : 0;
+
+ pData->pElements[pData->cElements].InitPass1(
+ dwNativeOffset,
+ pFunc,
+ ip,
+ flags);
+
+ // We'll init the IL offsets outside the TSL lock.
+
+ ++pData->cElements;
+
+ // check if we already have the number of frames that the user had asked for
+ if ((pData->NumFramesRequested != 0) && (pData->NumFramesRequested <= pData->cElements))
+ {
+ return SWA_ABORT;
+ }
+
+ return SWA_CONTINUE;
+}
+
+static void GetStackFrames(DebugStackTrace::GetStackFramesData *pData)
+{
+ CONTRACTL
+ {
+ MODE_COOPERATIVE;
+ GC_TRIGGERS;
+ THROWS;
+ }
+ CONTRACTL_END;
+
+ ASSERT (pData != NULL);
+
+ pData->cElements = 0;
+
+ // if the caller specified (< 20) frames are required, then allocate
+ // only that many
+ if ((pData->NumFramesRequested > 0) && (pData->NumFramesRequested < 20))
+ {
+ pData->cElementsAllocated = pData->NumFramesRequested;
+ }
+ else
+ {
+ pData->cElementsAllocated = 20;
+ }
+
+ // Allocate memory for the initial 'n' frames
+ pData->pElements = new DebugStackTrace::Element[pData->cElementsAllocated];
+ GetThread()->StackWalkFrames(GetStackFramesCallback, pData, FUNCTIONSONLY | QUICKUNWIND, NULL);
+
+ // Do a 2nd pass outside of any locks.
+ // This will compute IL offsets.
+ for (INT32 i = 0; i < pData->cElements; i++)
+ {
+ pData->pElements[i].InitPass2();
+ }
+}
+
+extern "C" void QCALLTYPE StackTrace_GetStackFramesInternal(
+ QCall::ObjectHandleOnStack stackFrameHelper,
+ BOOL fNeedFileInfo,
+ QCall::ObjectHandleOnStack exception)
+{
+ QCALL_CONTRACT;
- data.skip = iSkip;
+ BEGIN_QCALL;
- data.NumFramesRequested = pStackFrameHelper->iFrameCount;
+ GCX_COOP();
- if (pException == NULL)
+ struct
{
- // Thread is NULL if it's the current thread.
- data.TargetThread = pStackFrameHelper->targetThread;
- GetStackFrames(NULL, (void*)-1, &data);
+ STACKFRAMEHELPERREF pStackFrameHelper;
+ OBJECTREF pException;
+ PTRARRAYREF dynamicMethodArrayOrig;
+ } gc{};
+ gc.pStackFrameHelper = NULL;
+ gc.pException = NULL;
+ gc.dynamicMethodArrayOrig = NULL;
+ GCPROTECT_BEGIN(gc);
+ gc.pStackFrameHelper = (STACKFRAMEHELPERREF)stackFrameHelper.Get();
+ gc.pException = exception.Get();
+
+ DebugStackTrace::GetStackFramesData data;
+
+ data.pDomain = GetAppDomain();
+
+ data.NumFramesRequested = gc.pStackFrameHelper->iFrameCount;
+
+ if (gc.pException == NULL)
+ {
+ GetStackFrames(&data);
}
else
{
@@ -276,13 +374,17 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
// is thrown again (resetting the dynamic method array reference in the object)
// that may result in resolver objects getting collected before they can be reachable again
// (from the code below).
- GetStackFramesFromException(&pException, &data, &dynamicMethodArrayOrig);
+ DebugStackTrace::GetStackFramesFromException(&gc.pException, &data, &gc.dynamicMethodArrayOrig);
}
- if (data.cElements != 0)
+ if (data.cElements == 0)
+ {
+ gc.pStackFrameHelper->iFrameCount = 0;
+ }
+ else
{
#if defined(FEATURE_ISYM_READER) && defined(FEATURE_COMINTEROP)
- if (FC_ACCESS_BOOL(fNeedFileInfo))
+ if (fNeedFileInfo)
{
// Calls to COM up ahead.
EnsureComStarted();
@@ -291,59 +393,59 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
// Allocate memory for the MethodInfo objects
BASEARRAYREF methodInfoArray = (BASEARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_I, data.cElements);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgMethodHandle), (OBJECTREF)methodInfoArray);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgMethodHandle), (OBJECTREF)methodInfoArray);
// Allocate memory for the Offsets
OBJECTREF offsets = AllocatePrimitiveArray(ELEMENT_TYPE_I4, data.cElements);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgiOffset), (OBJECTREF)offsets);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgiOffset), (OBJECTREF)offsets);
// Allocate memory for the ILOffsets
OBJECTREF ilOffsets = AllocatePrimitiveArray(ELEMENT_TYPE_I4, data.cElements);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgiILOffset), (OBJECTREF)ilOffsets);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgiILOffset), (OBJECTREF)ilOffsets);
// Allocate memory for the array of assembly file names
PTRARRAYREF assemblyPathArray = (PTRARRAYREF) AllocateObjectArray(data.cElements, g_pStringClass);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgAssemblyPath), (OBJECTREF)assemblyPathArray);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgAssemblyPath), (OBJECTREF)assemblyPathArray);
// Allocate memory for the array of assemblies
PTRARRAYREF assemblyArray = (PTRARRAYREF) AllocateObjectArray(data.cElements, g_pObjectClass);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgAssembly), (OBJECTREF)assemblyArray);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgAssembly), (OBJECTREF)assemblyArray);
// Allocate memory for the LoadedPeAddress
BASEARRAYREF loadedPeAddressArray = (BASEARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_I, data.cElements);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgLoadedPeAddress), (OBJECTREF)loadedPeAddressArray);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgLoadedPeAddress), (OBJECTREF)loadedPeAddressArray);
// Allocate memory for the LoadedPeSize
OBJECTREF loadedPeSizeArray = AllocatePrimitiveArray(ELEMENT_TYPE_I4, data.cElements);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgiLoadedPeSize), (OBJECTREF)loadedPeSizeArray);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgiLoadedPeSize), (OBJECTREF)loadedPeSizeArray);
// Allocate memory for the IsFileLayout flags
OBJECTREF isFileLayouts = AllocatePrimitiveArray(ELEMENT_TYPE_BOOLEAN, data.cElements);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgiIsFileLayout), (OBJECTREF)isFileLayouts);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgiIsFileLayout), (OBJECTREF)isFileLayouts);
// Allocate memory for the InMemoryPdbAddress
BASEARRAYREF inMemoryPdbAddressArray = (BASEARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_I, data.cElements);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgInMemoryPdbAddress), (OBJECTREF)inMemoryPdbAddressArray);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgInMemoryPdbAddress), (OBJECTREF)inMemoryPdbAddressArray);
// Allocate memory for the InMemoryPdbSize
OBJECTREF inMemoryPdbSizeArray = AllocatePrimitiveArray(ELEMENT_TYPE_I4, data.cElements);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgiInMemoryPdbSize), (OBJECTREF)inMemoryPdbSizeArray);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgiInMemoryPdbSize), (OBJECTREF)inMemoryPdbSizeArray);
// Allocate memory for the MethodTokens
OBJECTREF methodTokens = AllocatePrimitiveArray(ELEMENT_TYPE_I4, data.cElements);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgiMethodToken), (OBJECTREF)methodTokens);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgiMethodToken), (OBJECTREF)methodTokens);
// Allocate memory for the Filename string objects
PTRARRAYREF filenameArray = (PTRARRAYREF) AllocateObjectArray(data.cElements, g_pStringClass);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgFilename), (OBJECTREF)filenameArray);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgFilename), (OBJECTREF)filenameArray);
// Allocate memory for the LineNumbers
OBJECTREF lineNumbers = AllocatePrimitiveArray(ELEMENT_TYPE_I4, data.cElements);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgiLineNumber), (OBJECTREF)lineNumbers);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgiLineNumber), (OBJECTREF)lineNumbers);
// Allocate memory for the ColumnNumbers
OBJECTREF columnNumbers = AllocatePrimitiveArray(ELEMENT_TYPE_I4, data.cElements);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgiColumnNumber), (OBJECTREF)columnNumbers);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgiColumnNumber), (OBJECTREF)columnNumbers);
// Allocate memory for the flag indicating if this frame represents the last one from a foreign
// exception stack trace provided we have any such frames. Otherwise, set it to null.
@@ -357,11 +459,11 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
{
IsLastFrameFromForeignStackTraceFlags = AllocatePrimitiveArray(ELEMENT_TYPE_BOOLEAN, data.cElements);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgiLastFrameFromForeignExceptionStackTrace), (OBJECTREF)IsLastFrameFromForeignStackTraceFlags);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgiLastFrameFromForeignExceptionStackTrace), (OBJECTREF)IsLastFrameFromForeignStackTraceFlags);
}
else
{
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgiLastFrameFromForeignExceptionStackTrace), NULL);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->rgiLastFrameFromForeignExceptionStackTrace), NULL);
}
// Determine if there are any dynamic methods in the stack trace. If there are,
@@ -385,7 +487,7 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
if (iNumDynamics)
{
PTRARRAYREF dynamicDataArray = (PTRARRAYREF) AllocateObjectArray(iNumDynamics, g_pObjectClass);
- SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->dynamicMethods), (OBJECTREF)dynamicDataArray);
+ SetObjectReference( (OBJECTREF *)&(gc.pStackFrameHelper->dynamicMethods), (OBJECTREF)dynamicDataArray);
}
int iNumValidFrames = 0;
@@ -401,25 +503,25 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
_ASSERTE(pFunc->IsRuntimeMethodHandle());
// Method handle
- size_t *pElem = (size_t*)pStackFrameHelper->rgMethodHandle->GetDataPtr();
+ size_t *pElem = (size_t*)gc.pStackFrameHelper->rgMethodHandle->GetDataPtr();
pElem[iNumValidFrames] = (size_t)pFunc;
// Native offset
- CLR_I4 *pI4 = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiOffset)->GetDirectPointerToNonObjectElements();
+ CLR_I4 *pI4 = (CLR_I4 *)((I4ARRAYREF)gc.pStackFrameHelper->rgiOffset)->GetDirectPointerToNonObjectElements();
pI4[iNumValidFrames] = data.pElements[i].dwOffset;
// IL offset
- CLR_I4 *pILI4 = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiILOffset)->GetDirectPointerToNonObjectElements();
+ CLR_I4 *pILI4 = (CLR_I4 *)((I4ARRAYREF)gc.pStackFrameHelper->rgiILOffset)->GetDirectPointerToNonObjectElements();
pILI4[iNumValidFrames] = data.pElements[i].dwILOffset;
// Assembly
OBJECTREF pAssembly = pFunc->GetAssembly()->GetExposedObject();
- pStackFrameHelper->rgAssembly->SetAt(iNumValidFrames, pAssembly);
+ gc.pStackFrameHelper->rgAssembly->SetAt(iNumValidFrames, pAssembly);
if (data.fDoWeHaveAnyFramesFromForeignStackTrace)
{
// Set the BOOL indicating if the frame represents the last frame from a foreign exception stack trace.
- CLR_U1 *pIsLastFrameFromForeignExceptionStackTraceU1 = (CLR_U1 *)((BOOLARRAYREF)pStackFrameHelper->rgiLastFrameFromForeignExceptionStackTrace)
+ CLR_U1 *pIsLastFrameFromForeignExceptionStackTraceU1 = (CLR_U1 *)((BOOLARRAYREF)gc.pStackFrameHelper->rgiLastFrameFromForeignExceptionStackTrace)
->GetDirectPointerToNonObjectElements();
pIsLastFrameFromForeignExceptionStackTraceU1 [iNumValidFrames] = (CLR_U1)(data.pElements[i].flags & STEF_LAST_FRAME_FROM_FOREIGN_STACK_TRACE);
}
@@ -436,13 +538,13 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
OBJECTREF pResolver = pDMD->GetLCGMethodResolver()->GetManagedResolver();
_ASSERTE(pResolver != NULL);
- ((PTRARRAYREF)pStackFrameHelper->dynamicMethods)->SetAt(iCurDynamic++, pResolver);
+ ((PTRARRAYREF)gc.pStackFrameHelper->dynamicMethods)->SetAt(iCurDynamic++, pResolver);
}
else if (pMethod->GetMethodTable()->Collectible())
{
OBJECTREF pLoaderAllocator = pMethod->GetMethodTable()->GetLoaderAllocator()->GetExposedObject();
_ASSERTE(pLoaderAllocator != NULL);
- ((PTRARRAYREF)pStackFrameHelper->dynamicMethods)->SetAt(iCurDynamic++, pLoaderAllocator);
+ ((PTRARRAYREF)gc.pStackFrameHelper->dynamicMethods)->SetAt(iCurDynamic++, pLoaderAllocator);
}
}
@@ -467,7 +569,7 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
}
#endif
// Check if the user wants the filenumber, linenumber info and that it is possible.
- if (!fIsEnc && FC_ACCESS_BOOL(fNeedFileInfo))
+ if (!fIsEnc && fNeedFileInfo)
{
#ifdef FEATURE_ISYM_READER
BOOL fPortablePDB = FALSE;
@@ -658,15 +760,15 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
if (fFileInfoSet)
{
// Set the line and column numbers
- CLR_I4 *pI4Line = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiLineNumber)->GetDirectPointerToNonObjectElements();
+ CLR_I4 *pI4Line = (CLR_I4 *)((I4ARRAYREF)gc.pStackFrameHelper->rgiLineNumber)->GetDirectPointerToNonObjectElements();
pI4Line[iNumValidFrames] = sourceLine;
- CLR_I4 *pI4Column = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiColumnNumber)->GetDirectPointerToNonObjectElements();
+ CLR_I4 *pI4Column = (CLR_I4 *)((I4ARRAYREF)gc.pStackFrameHelper->rgiColumnNumber)->GetDirectPointerToNonObjectElements();
pI4Column[iNumValidFrames] = sourceColumn;
// Set the file name
OBJECTREF obj = (OBJECTREF) StringObject::NewString(wszFileName);
- pStackFrameHelper->rgFilename->SetAt(iNumValidFrames, obj);
+ gc.pStackFrameHelper->rgFilename->SetAt(iNumValidFrames, obj);
}
}
@@ -676,7 +778,7 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
#endif // FEATURE_ISYM_READER
{
// Save MethodToken for the function
- CLR_I4 *pMethodToken = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiMethodToken)->GetDirectPointerToNonObjectElements();
+ CLR_I4 *pMethodToken = (CLR_I4 *)((I4ARRAYREF)gc.pStackFrameHelper->rgiMethodToken)->GetDirectPointerToNonObjectElements();
pMethodToken[iNumValidFrames] = pMethod->GetMemberDef();
PEAssembly *pPEAssembly = pModule->GetPEAssembly();
@@ -686,17 +788,17 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
PTR_CVOID peAddress = pPEAssembly->GetLoadedImageContents(&peSize);
// Save the PE address and size
- PTR_CVOID *pLoadedPeAddress = (PTR_CVOID *)pStackFrameHelper->rgLoadedPeAddress->GetDataPtr();
+ PTR_CVOID *pLoadedPeAddress = (PTR_CVOID *)gc.pStackFrameHelper->rgLoadedPeAddress->GetDataPtr();
pLoadedPeAddress[iNumValidFrames] = peAddress;
- CLR_I4 *pLoadedPeSize = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiLoadedPeSize)->GetDirectPointerToNonObjectElements();
+ CLR_I4 *pLoadedPeSize = (CLR_I4 *)((I4ARRAYREF)gc.pStackFrameHelper->rgiLoadedPeSize)->GetDirectPointerToNonObjectElements();
pLoadedPeSize[iNumValidFrames] = (CLR_I4)peSize;
// Set flag indicating PE file in memory has the on disk layout
if (!pPEAssembly->IsReflectionEmit())
{
// This flag is only available for non-dynamic assemblies.
- CLR_U1 *pIsFileLayout = (CLR_U1 *)((BOOLARRAYREF)pStackFrameHelper->rgiIsFileLayout)->GetDirectPointerToNonObjectElements();
+ CLR_U1 *pIsFileLayout = (CLR_U1 *)((BOOLARRAYREF)gc.pStackFrameHelper->rgiIsFileLayout)->GetDirectPointerToNonObjectElements();
pIsFileLayout[iNumValidFrames] = (CLR_U1) pPEAssembly->GetLoadedLayout()->IsFlat();
}
@@ -707,10 +809,10 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
MemoryRange range = stream->GetRawBuffer();
// Save the in-memory PDB address and size
- PTR_VOID *pInMemoryPdbAddress = (PTR_VOID *)pStackFrameHelper->rgInMemoryPdbAddress->GetDataPtr();
+ PTR_VOID *pInMemoryPdbAddress = (PTR_VOID *)gc.pStackFrameHelper->rgInMemoryPdbAddress->GetDataPtr();
pInMemoryPdbAddress[iNumValidFrames] = range.StartAddress();
- CLR_I4 *pInMemoryPdbSize = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiInMemoryPdbSize)->GetDirectPointerToNonObjectElements();
+ CLR_I4 *pInMemoryPdbSize = (CLR_I4 *)((I4ARRAYREF)gc.pStackFrameHelper->rgiInMemoryPdbSize)->GetDirectPointerToNonObjectElements();
pInMemoryPdbSize[iNumValidFrames] = (CLR_I4)range.Size();
}
else
@@ -720,7 +822,7 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
if (!assemblyPath.IsEmpty())
{
OBJECTREF obj = (OBJECTREF)StringObject::NewString(assemblyPath.GetUnicode());
- pStackFrameHelper->rgAssemblyPath->SetAt(iNumValidFrames, obj);
+ gc.pStackFrameHelper->rgAssemblyPath->SetAt(iNumValidFrames, obj);
}
}
}
@@ -729,20 +831,15 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
iNumValidFrames++;
}
- pStackFrameHelper->iFrameCount = iNumValidFrames;
- }
- else
- {
- pStackFrameHelper->iFrameCount = 0;
+ gc.pStackFrameHelper->iFrameCount = iNumValidFrames;
}
GCPROTECT_END();
- HELPER_METHOD_FRAME_END();
+ END_QCALL;
}
-FCIMPLEND
-extern MethodDesc* QCALLTYPE StackFrame_GetMethodDescFromNativeIP(LPVOID ip)
+extern "C" MethodDesc* QCALLTYPE StackFrame_GetMethodDescFromNativeIP(LPVOID ip)
{
QCALL_CONTRACT;
@@ -770,242 +867,39 @@ typedef Wrapper, HolderDestroyStrongHandle
// receives a custom notification object from the target and sends it to the RS via
// code:Debugger::SendCustomDebuggerNotification
// Argument: dataUNSAFE - a pointer the custom notification object being sent
-FCIMPL1(void, DebugDebugger::CustomNotification, Object * dataUNSAFE)
+extern "C" void QCALLTYPE DebugDebugger_CustomNotification(QCall::ObjectHandleOnStack data)
{
- CONTRACTL
- {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- OBJECTREF pData = ObjectToOBJECTREF(dataUNSAFE);
+ QCALL_CONTRACT;
#ifdef DEBUGGING_SUPPORTED
// Send notification only if the debugger is attached
- if (CORDebuggerAttached() )
- {
- HELPER_METHOD_FRAME_BEGIN_PROTECT(pData);
-
- Thread * pThread = GetThread();
- AppDomain * pAppDomain = AppDomain::GetCurrentDomain();
-
- StrongHandleHolder objHandle = pAppDomain->CreateStrongHandle(pData);
- MethodTable * pMT = pData->GetGCSafeMethodTable();
- Module * pModule = pMT->GetModule();
- DomainAssembly * pDomainAssembly = pModule->GetDomainAssembly();
- mdTypeDef classToken = pMT->GetCl();
-
- pThread->SetThreadCurrNotification(objHandle);
- g_pDebugInterface->SendCustomDebuggerNotification(pThread, pDomainAssembly, classToken);
- pThread->ClearThreadCurrNotification();
-
- if (pThread->IsAbortRequested())
- {
- pThread->HandleThreadAbort();
- }
-
- HELPER_METHOD_FRAME_END();
- }
-
-#endif // DEBUGGING_SUPPORTED
-
-}
-FCIMPLEND
-
-
-void DebugStackTrace::GetStackFramesHelper(Frame *pStartFrame,
- void* pStopStack,
- GetStackFramesData *pData
- )
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END;
-
- ASSERT (pData != NULL);
-
- pData->cElements = 0;
-
- // if the caller specified (< 20) frames are required, then allocate
- // only that many
- if ((pData->NumFramesRequested > 0) && (pData->NumFramesRequested < 20))
- {
- pData->cElementsAllocated = pData->NumFramesRequested;
- }
- else
- {
- pData->cElementsAllocated = 20;
- }
-
- // Allocate memory for the initial 'n' frames
- pData->pElements = new DebugStackTraceElement[pData->cElementsAllocated];
-
- if (pData->TargetThread == NULL ||
- pData->TargetThread->GetInternal() == GetThread())
- {
- // Null target thread specifies current thread.
- GetThread()->StackWalkFrames(GetStackFramesCallback, pData, FUNCTIONSONLY | QUICKUNWIND, pStartFrame);
- }
- else
- {
- Thread *pThread = pData->TargetThread->GetInternal();
- _ASSERTE (pThread != NULL);
-
- // Here's the timeline for the TS_SyncSuspended bit.
- // 0) TS_SyncSuspended is not set.
- // 1) The suspending thread grabs the thread store lock
- // then puts in place trip wires for the suspendee (if it is in managed code)
- // and releases the thread store lock.
- // 2) The suspending thread waits for the "SafeEvent".
- // 3) The suspendee continues execution until it tries to enter preemptive mode.
- // If it trips over the wires put in place by the suspending thread,
- // it will try to enter preemptive mode.
- // 4) The suspendee sets TS_SyncSuspended and the "SafeEvent".
- // 5) AT THIS POINT, IT IS SAFE TO WALK THE SUSPENDEE'S STACK.
- // 6) The suspendee clears the TS_SyncSuspended flag.
- //
- // In other words, it is safe to trace the thread's stack IF we're holding the
- // thread store lock AND TS_SyncSuspended is set.
- //
- // This is because:
- // - If we were not holding the thread store lock, the thread could be resumed
- // underneath us.
- // - When TS_SyncSuspended is set, we race against it resuming execution.
-
- ThreadStoreLockHolder tsl;
-
- // We erect a barrier so that if the thread tries to disable preemptive GC,
- // it could resume execution of managed code during our stack walk.
- TSSuspendHolder shTrap;
-
- Thread::ThreadState state = pThread->GetSnapshotState();
- if (state & (Thread::TS_Unstarted|Thread::TS_Dead|Thread::TS_Detached))
- {
- goto LSafeToTrace;
- }
-
- COMPlusThrow(kThreadStateException, IDS_EE_THREAD_BAD_STATE);
-
- LSafeToTrace:
- pThread->StackWalkFrames(GetStackFramesCallback,
- pData,
- FUNCTIONSONLY|ALLOW_ASYNC_STACK_WALK,
- pStartFrame);
- }
-
- // Do a 2nd pass outside of any locks.
- // This will compute IL offsets.
- for (INT32 i = 0; i < pData->cElements; i++)
- {
- pData->pElements[i].InitPass2();
- }
-
-}
-
-
-void DebugStackTrace::GetStackFrames(Frame *pStartFrame,
- void* pStopStack,
- GetStackFramesData *pData
- )
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- GetStackFramesHelper(pStartFrame, pStopStack, pData);
-}
-
-
-StackWalkAction DebugStackTrace::GetStackFramesCallback(CrawlFrame* pCf, VOID* data)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- GetStackFramesData* pData = (GetStackFramesData*)data;
-
- if (pData->skip > 0)
- {
- pData->skip--;
- return SWA_CONTINUE;
- }
-
- // @todo: How do we know what kind of frame we have?
- // Can we always assume FramedMethodFrame?
- // NOT AT ALL!!!, but we can assume it's a function
- // because we asked the stackwalker for it!
- MethodDesc* pFunc = pCf->GetFunction();
-
- if (pData->cElements >= pData->cElementsAllocated)
- {
-
- DebugStackTraceElement* pTemp = new (nothrow) DebugStackTraceElement[2*pData->cElementsAllocated];
-
- if (!pTemp)
- {
- return SWA_ABORT;
- }
-
- memcpy(pTemp, pData->pElements, pData->cElementsAllocated * sizeof(DebugStackTraceElement));
-
- delete [] pData->pElements;
-
- pData->pElements = pTemp;
- pData->cElementsAllocated *= 2;
- }
-
- PCODE ip;
- DWORD dwNativeOffset;
-
- if (pCf->IsFrameless())
- {
- // Real method with jitted code.
- dwNativeOffset = pCf->GetRelOffset();
- ip = GetControlPC(pCf->GetRegisterSet());
- }
- else
- {
- ip = (PCODE)NULL;
- dwNativeOffset = 0;
- }
+ if (!CORDebuggerAttached())
+ return;
- // Pass on to InitPass2 that the IP has already been adjusted (decremented by 1)
- INT flags = pCf->IsIPadjusted() ? STEF_IP_ADJUSTED : 0;
+ BEGIN_QCALL;
- pData->pElements[pData->cElements].InitPass1(
- dwNativeOffset,
- pFunc,
- ip,
- flags);
+ GCX_COOP();
- // We'll init the IL offsets outside the TSL lock.
+ Thread * pThread = GetThread();
+ AppDomain * pAppDomain = AppDomain::GetCurrentDomain();
- ++pData->cElements;
+ StrongHandleHolder objHandle = pAppDomain->CreateStrongHandle(data.Get());
+ MethodTable* pMT = data.Get()->GetGCSafeMethodTable();
+ Module* pModule = pMT->GetModule();
+ DomainAssembly* pDomainAssembly = pModule->GetDomainAssembly();
+ mdTypeDef classToken = pMT->GetCl();
- // Since we may be asynchronously walking another thread's stack,
- // check (frequently) for stack-buffer-overrun corruptions after
- // any long operation
- pCf->CheckGSCookies();
+ pThread->SetThreadCurrNotification(objHandle);
+ g_pDebugInterface->SendCustomDebuggerNotification(pThread, pDomainAssembly, classToken);
+ pThread->ClearThreadCurrNotification();
- // check if we already have the number of frames that the user had asked for
- if ((pData->NumFramesRequested != 0) && (pData->NumFramesRequested <= pData->cElements))
+ if (pThread->IsAbortRequested())
{
- return SWA_ABORT;
+ pThread->HandleThreadAbort();
}
- return SWA_CONTINUE;
+ END_QCALL;
+#endif // DEBUGGING_SUPPORTED
}
#endif // !DACCESS_COMPILE
@@ -1057,7 +951,7 @@ void DebugStackTrace::GetStackFramesFromException(OBJECTREF * e,
if (pData->cElements != 0)
{
// Allocate the memory to contain the data
- pData->pElements = new DebugStackTraceElement[pData->cElements];
+ pData->pElements = new Element[pData->cElements];
// Fill in the data
for (unsigned i = 0; i < (unsigned)pData->cElements; i++)
@@ -1123,7 +1017,7 @@ void DebugStackTrace::GetStackFramesFromException(OBJECTREF * e,
// Init a stack-trace element.
// Initialization done potentially under the TSL.
-void DebugStackTrace::DebugStackTraceElement::InitPass1(
+void DebugStackTrace::Element::InitPass1(
DWORD dwNativeOffset,
MethodDesc *pFunc,
PCODE ip,
@@ -1146,7 +1040,7 @@ void DebugStackTrace::DebugStackTraceElement::InitPass1(
// Initialization done outside the TSL.
// This may need to call locking operations that aren't safe under the TSL.
-void DebugStackTrace::DebugStackTraceElement::InitPass2()
+void DebugStackTrace::Element::InitPass2()
{
CONTRACTL
{
diff --git a/src/coreclr/vm/debugdebugger.h b/src/coreclr/vm/debugdebugger.h
index fa630cbb46e28e..bbf06268752c5c 100644
--- a/src/coreclr/vm/debugdebugger.h
+++ b/src/coreclr/vm/debugdebugger.h
@@ -19,19 +19,15 @@
class DebugDebugger
{
public:
- static FCDECL0(void, Break);
static FCDECL0(FC_BOOL_RET, IsDebuggerAttached);
- // receives a custom notification object from the target and sends it to the RS via
- // code:Debugger::SendCustomDebuggerNotification
- static FCDECL1(void, CustomNotification, Object * dataUNSAFE);
-
static FCDECL0(FC_BOOL_RET, IsLogging);
};
+extern "C" void QCALLTYPE DebugDebugger_Break();
extern "C" BOOL QCALLTYPE DebugDebugger_Launch();
extern "C" void QCALLTYPE DebugDebugger_Log(INT32 Level, PCWSTR pwzModule, PCWSTR pwzMessage);
-
+extern "C" void QCALLTYPE DebugDebugger_CustomNotification(QCall::ObjectHandleOnStack data);
class StackFrameHelper : public Object
{
@@ -39,7 +35,6 @@ class StackFrameHelper : public Object
// Modifying the order or fields of this object may require other changes to the
// classlib definition of the StackFrameHelper class.
public:
- THREADBASEREF targetThread;
I4ARRAYREF rgiOffset;
I4ARRAYREF rgiILOffset;
PTRARRAYREF dynamicMethods;
@@ -88,12 +83,7 @@ typedef StackFrameHelper* STACKFRAMEHELPERREF;
class DebugStackTrace
{
public:
-
-#ifndef DACCESS_COMPILE
-// the DAC directly uses the GetStackFramesData and DebugStackTraceElement types
-private:
-#endif // DACCESS_COMPILE
- struct DebugStackTraceElement {
+ struct Element {
DWORD dwOffset; // native offset
DWORD dwILOffset;
MethodDesc *pFunc;
@@ -117,29 +107,25 @@ class DebugStackTrace
public:
- struct GetStackFramesData {
-
- // Used for the integer-skip version
- INT32 skip;
+ struct GetStackFramesData
+ {
INT32 NumFramesRequested;
INT32 cElementsAllocated;
INT32 cElements;
- DebugStackTraceElement* pElements;
+ Element* pElements;
THREADBASEREF TargetThread;
AppDomain *pDomain;
BOOL fDoWeHaveAnyFramesFromForeignStackTrace;
-
- GetStackFramesData() : skip(0),
- NumFramesRequested (0),
- cElementsAllocated(0),
- cElements(0),
- pElements(NULL),
- TargetThread((THREADBASEREF)(TADDR)NULL)
+ GetStackFramesData()
+ : NumFramesRequested (0)
+ , cElementsAllocated(0)
+ , cElements(0)
+ , pElements(NULL)
+ , TargetThread((THREADBASEREF)(TADDR)NULL)
+ , fDoWeHaveAnyFramesFromForeignStackTrace(FALSE)
{
LIMITED_METHOD_CONTRACT;
- fDoWeHaveAnyFramesFromForeignStackTrace = FALSE;
-
}
~GetStackFramesData()
@@ -148,29 +134,14 @@ class DebugStackTrace
}
};
- static FCDECL4(void,
- GetStackFramesInternal,
- StackFrameHelper* pStackFrameHelper,
- INT32 iSkip,
- FC_BOOL_ARG fNeedFileInfo,
- Object* pException
- );
-
static void GetStackFramesFromException(OBJECTREF * e, GetStackFramesData *pData, PTRARRAYREF * pDynamicMethodArray = NULL);
-
-#ifndef DACCESS_COMPILE
-// the DAC directly calls GetStackFramesFromException
-private:
-#endif
-
- static void GetStackFramesHelper(Frame *pStartFrame, void* pStopStack, GetStackFramesData *pData);
-
- static void GetStackFrames(Frame *pStartFrame, void* pStopStack, GetStackFramesData *pData);
-
- static StackWalkAction GetStackFramesCallback(CrawlFrame* pCf, VOID* data);
-
};
+extern "C" void QCALLTYPE StackTrace_GetStackFramesInternal(
+ QCall::ObjectHandleOnStack stackFrameHelper,
+ BOOL fNeedFileInfo,
+ QCall::ObjectHandleOnStack exception);
+
extern "C" MethodDesc* QCALLTYPE StackFrame_GetMethodDescFromNativeIP(LPVOID ip);
#endif // __DEBUG_DEBUGGER_h__
diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h
index 9cadd51c06ae4b..baed6b5cda2eaf 100644
--- a/src/coreclr/vm/ecalllist.h
+++ b/src/coreclr/vm/ecalllist.h
@@ -68,14 +68,8 @@ FCFuncStart(gStringFuncs)
FCFuncEnd()
FCFuncStart(gDiagnosticsDebugger)
- FCFuncElement("BreakInternal", DebugDebugger::Break)
FCFuncElement("get_IsAttached", DebugDebugger::IsDebuggerAttached)
FCFuncElement("IsLogging", DebugDebugger::IsLogging)
- FCFuncElement("CustomNotification", DebugDebugger::CustomNotification)
-FCFuncEnd()
-
-FCFuncStart(gDiagnosticsStackTrace)
- FCFuncElement("GetStackFramesInternal", DebugStackTrace::GetStackFramesInternal)
FCFuncEnd()
FCFuncStart(gEnvironmentFuncs)
@@ -515,7 +509,6 @@ FCClassElement("RuntimeType", "System", gSystem_RuntimeType)
FCClassElement("RuntimeTypeHandle", "System", gCOMTypeHandleFuncs)
FCClassElement("Signature", "System", gSignatureNative)
-FCClassElement("StackTrace", "System.Diagnostics", gDiagnosticsStackTrace)
FCClassElement("Stream", "System.IO", gStreamFuncs)
FCClassElement("String", "System", gStringFuncs)
FCClassElement("StubHelpers", "System.StubHelpers", gStubHelperFuncs)
diff --git a/src/coreclr/vm/eventreporter.cpp b/src/coreclr/vm/eventreporter.cpp
index 9a4d01b8af9711..8ffab60bbd94c1 100644
--- a/src/coreclr/vm/eventreporter.cpp
+++ b/src/coreclr/vm/eventreporter.cpp
@@ -632,7 +632,6 @@ void ReportExceptionStackHelper(OBJECTREF exObj, EventReporter& reporter, SmallS
DebugStackTrace::GetStackFramesData stackFramesData;
stackFramesData.pDomain = NULL;
- stackFramesData.skip = 0;
stackFramesData.NumFramesRequested = 0;
DebugStackTrace::GetStackFramesFromException(&(gc.exObj), &stackFramesData);
diff --git a/src/coreclr/vm/i386/jitinterfacex86.cpp b/src/coreclr/vm/i386/jitinterfacex86.cpp
index 0b6607aff6d2a8..f643365aae56ff 100644
--- a/src/coreclr/vm/i386/jitinterfacex86.cpp
+++ b/src/coreclr/vm/i386/jitinterfacex86.cpp
@@ -96,25 +96,6 @@ extern "C" void STDCALL WriteBarrierAssert(BYTE* ptr, Object* obj)
#endif // _DEBUG
-FCDECL1(Object*, JIT_New, CORINFO_CLASS_HANDLE typeHnd_);
-
-
-HCIMPL1(Object*, AllocObjectWrapper, MethodTable *pMT)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- OBJECTREF newObj = NULL;
- HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame
- newObj = AllocateObject(pMT);
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(newObj);
-}
-HCIMPLEND
-
/*********************************************************************/
#ifndef UNIX_X86_ABI
extern "C" void* g_TailCallFrameVptr;
@@ -361,6 +342,8 @@ void JIT_TrialAlloc::EmitNoAllocCode(CPUSTUBLINKER *psl, Flags flags)
}
}
+FCDECL1(Object*, JIT_New, CORINFO_CLASS_HANDLE typeHnd_);
+
void *JIT_TrialAlloc::GenAllocSFast(Flags flags)
{
STANDARD_VM_CONTRACT;
diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp
index 108738af6b9cca..9704f216958b3a 100644
--- a/src/coreclr/vm/qcallentrypoints.cpp
+++ b/src/coreclr/vm/qcallentrypoints.cpp
@@ -83,8 +83,10 @@ static const Entry s_QCall[] =
DllImportEntry(CustomAttribute_CreateCustomAttributeInstance)
DllImportEntry(CustomAttribute_CreatePropertyOrFieldData)
DllImportEntry(Enum_GetValuesAndNames)
+ DllImportEntry(DebugDebugger_Break)
DllImportEntry(DebugDebugger_Launch)
DllImportEntry(DebugDebugger_Log)
+ DllImportEntry(DebugDebugger_CustomNotification)
DllImportEntry(Delegate_BindToMethodName)
DllImportEntry(Delegate_BindToMethodInfo)
DllImportEntry(Delegate_InitializeVirtualCallStub)
@@ -138,6 +140,7 @@ static const Entry s_QCall[] =
DllImportEntry(RuntimeModule_GetFullyQualifiedName)
DllImportEntry(RuntimeModule_GetTypes)
DllImportEntry(RuntimeFieldHandle_GetRVAFieldInfo)
+ DllImportEntry(StackTrace_GetStackFramesInternal)
DllImportEntry(StackFrame_GetMethodDescFromNativeIP)
DllImportEntry(ModuleBuilder_GetStringConstant)
DllImportEntry(ModuleBuilder_GetTypeRef)
diff --git a/src/coreclr/vm/threads.h b/src/coreclr/vm/threads.h
index 4a4bd2ff867fa7..6aa3e04b004652 100644
--- a/src/coreclr/vm/threads.h
+++ b/src/coreclr/vm/threads.h
@@ -4267,12 +4267,6 @@ struct cdac_data
static constexpr size_t DeadCount = offsetof(ThreadStore, m_DeadThreadCount);
};
-struct TSSuspendHelper {
- static void SetTrap() { ThreadStore::IncrementTrapReturningThreads(); }
- static void UnsetTrap() { ThreadStore::DecrementTrapReturningThreads(); }
-};
-typedef StateHolder TSSuspendHolder;
-
typedef StateHolder ThreadStoreLockHolder;