This commit is contained in:
mikelle-rogers 2025-07-30 07:03:32 -07:00 committed by GitHub
commit 52179fe2fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 132 additions and 6 deletions

View File

@ -1103,7 +1103,8 @@ DebuggerController::DebuggerController(Thread * pThread, AppDomain * pAppDomain)
m_deleted(false),
m_fEnableMethodEnter(false),
m_multicastDelegateHelper(false),
m_externalMethodFixup(false)
m_externalMethodFixup(false),
m_genericPInvokeCalli(false)
{
CONTRACTL
{
@ -1297,6 +1298,8 @@ void DebuggerController::DisableAll()
DisableMultiCastDelegate();
if (m_externalMethodFixup)
DisableExternalMethodFixup();
if (m_genericPInvokeCalli)
DisableGenericPInvokeCalli();
}
}
@ -2562,6 +2565,10 @@ bool DebuggerController::PatchTrace(TraceDestination *trace,
EnableExternalMethodFixup();
return true;
case TRACE_GENERIC_PINVOKE_CALLI:
EnableGenericPInvokeCalli();
return true;
case TRACE_OTHER:
LOG((LF_CORDB, LL_INFO10000,
"Can't set a trace patch for TRACE_OTHER...\n"));
@ -4208,6 +4215,68 @@ void DebuggerController::DispatchExternalMethodFixup(PCODE addr)
p = p->m_next;
}
}
void DebuggerController::EnableGenericPInvokeCalli()
{
CONTRACTL
{
NOTHROW;
GC_NOTRIGGER;
}
CONTRACTL_END;
ControllerLockHolder chController;
if (!m_genericPInvokeCalli)
{
LOG((LF_CORDB, LL_INFO1000000, "DC::EnableGenericPInvokeCalli, this=%p, previously disabled\n", this));
m_genericPInvokeCalli = true;
g_genericPInvokeCalliHelperTraceActiveCount += 1;
}
else
{
LOG((LF_CORDB, LL_INFO1000000, "DC::EnableGenericPInvokeCalli, this=%p, already set\n", this));
}
}
void DebuggerController::DisableGenericPInvokeCalli()
{
CONTRACTL
{
NOTHROW;
GC_NOTRIGGER;
}
CONTRACTL_END;
ControllerLockHolder chController;
if (m_genericPInvokeCalli)
{
LOG((LF_CORDB, LL_INFO10000, "DC::DisableGenericPInvokeCalli, this=%p, previously set\n", this));
m_genericPInvokeCalli = false;
g_genericPInvokeCalliHelperTraceActiveCount -= 1;
}
else
{
LOG((LF_CORDB, LL_INFO10000, "DC::DisableGenericPInvokeCalli, this=%p, already disabled\n", this));
}
}
// Loop through controllers and dispatch TriggerGenericPInvokeCalli
void DebuggerController::DispatchGenericPInvokeCalli(PCODE addr)
{
Thread * pThread = g_pEEInterface->GetThread();
_ASSERTE(pThread != NULL);
ControllerLockHolder lockController;
DebuggerController *p = g_controllers;
while (p != NULL)
{
if (p->m_genericPInvokeCalli)
{
if ((p->GetThread() == NULL) || (p->GetThread() == pThread))
{
p->TriggerGenericPInvokeCalli(addr);
}
}
p = p->m_next;
}
}
//
// AddProtection adds page protection to (at least) the given range of
// addresses
@ -4360,6 +4429,10 @@ void DebuggerController::TriggerExternalMethodFixup(PCODE target)
{
_ASSERTE(!"This code should be unreachable. If your controller enables ExternalMethodFixup events, it should also override this callback to do something useful when the event arrives.");
}
void DebuggerController::TriggerGenericPInvokeCalli(PCODE target)
{
_ASSERTE(!"This code should be unreachable. If your controller enables GenericPInvokeCalli events, it should also override this callback to do something useful when the event arrives.");
}
#ifdef _DEBUG
@ -7807,6 +7880,19 @@ void DebuggerStepper::TriggerExternalMethodFixup(PCODE target)
this->DisableExternalMethodFixup();
}
void DebuggerStepper::TriggerGenericPInvokeCalli(PCODE target)
{
TraceDestination trace;
FramePointer fp = LEAF_MOST_FRAME;
trace.InitForStub(target);
bool hasTraceType = g_pEEInterface->FollowTrace(&trace);
//fStopInUnmanaged only matters for TRACE_UNMANAGED
_ASSERTE(hasTraceType);
bool setPatch = PatchTrace(&trace, fp, /*fStopInUnmanaged*/false);
_ASSERTE(setPatch);
this->DisableGenericPInvokeCalli();
}
// Prepare for sending an event.
// This is called 1:1 w/ SendEvent, but this method can be called in a GC_TRIGGERABLE context
// whereas SendEvent is pretty strict.

View File

@ -1104,7 +1104,7 @@ class DebuggerController
static void DispatchMethodEnter(void * pIP, FramePointer fp);
static void DispatchMulticastDelegate(DELEGATEREF pbDel, INT32 countDel);
static void DispatchExternalMethodFixup(PCODE addr);
static void DispatchGenericPInvokeCalli(PCODE addr);
// Delete any patches that exist for a specific module and optionally a specific AppDomain.
// If pAppDomain is specified, then only patches tied to the specified AppDomain are
@ -1330,6 +1330,9 @@ public:
void EnableExternalMethodFixup();
void DisableExternalMethodFixup();
void EnableGenericPInvokeCalli();
void DisableGenericPInvokeCalli();
void DisableAll();
virtual DEBUGGER_CONTROLLER_TYPE GetDCType( void )
@ -1433,6 +1436,8 @@ public:
virtual void TriggerExternalMethodFixup(PCODE target);
virtual void TriggerGenericPInvokeCalli(PCODE target);
// Send the managed debug event.
// This is called after TriggerPatch/TriggerSingleStep actually trigger.
// Note this can have a strange interaction with SetIp. Specifically this thread:
@ -1473,7 +1478,7 @@ private:
bool m_fEnableMethodEnter;
bool m_multicastDelegateHelper;
bool m_externalMethodFixup;
bool m_genericPInvokeCalli;
#endif // !DACCESS_COMPILE
};
@ -1710,6 +1715,7 @@ protected:
virtual void TriggerMethodEnter(Thread * thread, DebuggerJitInfo * dji, const BYTE * ip, FramePointer fp);
void TriggerMulticastDelegate(DELEGATEREF pDel, INT32 delegateCount);
void TriggerExternalMethodFixup(PCODE target);
void TriggerGenericPInvokeCalli(PCODE target);
void ResetRange();

View File

@ -16260,10 +16260,16 @@ void Debugger::MulticastTraceNextStep(DELEGATEREF pbDel, INT32 count)
{
DebuggerController::DispatchMulticastDelegate(pbDel, count);
}
void Debugger::ExternalMethodFixupNextStep(PCODE address)
{
DebuggerController::DispatchExternalMethodFixup(address);
}
void Debugger::GenericPInvokeCalliNextStep(PCODE address)
{
DebuggerController::DispatchGenericPInvokeCalli(address);
}
#endif //DACCESS_COMPILE
unsigned FuncEvalFrame::GetFrameAttribs_Impl(void)

View File

@ -2607,6 +2607,7 @@ public:
#ifndef DACCESS_COMPILE
void MulticastTraceNextStep(DELEGATEREF pbDel, INT32 count);
void ExternalMethodFixupNextStep(PCODE address);
void GenericPInvokeCalliNextStep(PCODE address);
#endif
#ifdef DACCESS_COMPILE

View File

@ -398,6 +398,7 @@ public:
virtual HRESULT IsMethodDeoptimized(Module *pModule, mdMethodDef methodDef, BOOL *pResult) = 0;
virtual void MulticastTraceNextStep(DELEGATEREF pbDel, INT32 count) = 0;
virtual void ExternalMethodFixupNextStep(PCODE address) = 0;
virtual void GenericPInvokeCalliNextStep(PCODE address) = 0;
#endif //DACCESS_COMPILE
};

View File

@ -38,7 +38,7 @@
#include "pinvokeoverride.h"
#include "nativelibrary.h"
#include "interoplibinterface.h"
#include "../debug/ee/debugger.h"
#include <formattype.h>
#include "../md/compiler/custattr.h"
@ -6090,6 +6090,11 @@ PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD)
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER;
if (g_genericPInvokeCalliHelperTraceActiveCount > 0)
{
g_pDebugger->GenericPInvokeCalliNextStep(pVASigCookie->pNDirectILStub);
}
RETURN pVASigCookie->pNDirectILStub;
}

View File

@ -29,6 +29,7 @@ const char *GetTType( TraceType tt)
case TRACE_UNJITTED_METHOD: return "TRACE_UNJITTED_METHOD";
case TRACE_MULTICAST_DELEGATE_HELPER: return "TRACE_MULTICAST_DELEGATE_HELPER";
case TRACE_EXTERNAL_METHOD_FIXUP: return "TRACE_EXTERNAL_METHOD_FIXUP";
case TRACE_GENERIC_PINVOKE_CALLI: return "TRACE_GENERIC_PINVOKE_CALLI";
}
return "TRACE_REALLY_WACKED";
}
@ -128,6 +129,10 @@ const CHAR * TraceDestination::DbgToString(SString & buffer)
pValue = "TRACE_EXTERNAL_METHOD_FIXUP";
break;
case TRACE_GENERIC_PINVOKE_CALLI:
pValue = "TRACE_GENERIC_PINVOKE_CALLI";
break;
case TRACE_OTHER:
pValue = "TRACE_OTHER";
break;
@ -1919,8 +1924,14 @@ BOOL InteropDispatchStubManager::DoTraceStub(PCODE stubStartAddress, TraceDestin
#ifndef DACCESS_COMPILE
_ASSERTE(CheckIsStub_Internal(stubStartAddress));
trace->InitForManagerPush(stubStartAddress, this);
if (stubStartAddress == GetEEFuncEntryPoint(GenericPInvokeCalliHelper))
{
trace->InitForGenericPInvokeCalli();
}
else
{
trace->InitForManagerPush(stubStartAddress, this);
}
LOG_TRACE_DESTINATION(trace, stubStartAddress, "InteropDispatchStubManager::DoTraceStub");

View File

@ -63,6 +63,7 @@ enum TraceType
TRACE_MGR_PUSH, // Don't know where stub goes, stop at address then call TraceManager() below to find out
TRACE_MULTICAST_DELEGATE_HELPER, // Stub goes to a multicast delegate helper
TRACE_EXTERNAL_METHOD_FIXUP, // Stub goes to an external method fixup helper
TRACE_GENERIC_PINVOKE_CALLI, // Stub goes to a generic PInvoke Calli helper
TRACE_OTHER // We are going somewhere you can't step into (eg. ee helper function)
};
@ -164,6 +165,13 @@ public:
this->stubManager = NULL;
}
void InitForGenericPInvokeCalli()
{
this->type = TRACE_GENERIC_PINVOKE_CALLI;
this->address = (PCODE)NULL;
this->stubManager = NULL;
}
// Nobody recognized the target address. We will not be able to step-in to it.
// This is ok if the target just calls into mscorwks (such as an Fcall) because
// there's no managed code to step in to, and we don't support debugging the CLR

View File

@ -147,6 +147,7 @@ GPTR_IMPL(EEDbgInterfaceImpl, g_pEEDbgInterfaceImpl);
#ifndef DACCESS_COMPILE
GVAL_IMPL_INIT(DWORD, g_multicastDelegateTraceActiveCount, 0);
GVAL_IMPL_INIT(DWORD, g_externalMethodFixupTraceActiveCount, 0);
GVAL_IMPL_INIT(DWORD, g_genericPInvokeCalliHelperTraceActiveCount, 0);
#endif // DACCESS_COMPILE
#endif // DEBUGGING_SUPPORTED

View File

@ -415,6 +415,7 @@ GPTR_DECL(EEDbgInterfaceImpl, g_pEEDbgInterfaceImpl);
#ifndef DACCESS_COMPILE
GVAL_DECL(DWORD, g_multicastDelegateTraceActiveCount);
GVAL_DECL(DWORD, g_externalMethodFixupTraceActiveCount);
GVAL_DECL(DWORD, g_genericPInvokeCalliHelperTraceActiveCount);
#endif // DACCESS_COMPILE
#endif // DEBUGGING_SUPPORTED