@@ -25,6 +25,11 @@ const char *GetTType( TraceType tt);
2525
2626#define IsSingleStep (exception ) ((exception) == EXCEPTION_SINGLE_STEP )
2727
28+ typedef enum __TailCallFunctionType {
29+ TailCallThatReturns = 1 ,
30+ StoreTailCallArgs = 2
31+ } TailCallFunctionType;
32+
2833// -------------------------------------------------------------------------
2934// DebuggerController routines
3035// -------------------------------------------------------------------------
@@ -5789,10 +5794,10 @@ static bool IsTailCallJitHelper(const BYTE * ip)
57895794// control flow will be a little peculiar in that the function will return
57905795// immediately, so we need special handling in the debugger for it. This
57915796// function detects that case to be used for those scenarios.
5792- static bool IsTailCallThatReturns (const BYTE * ip, ControllerStackInfo* info)
5797+ static bool IsTailCall (const BYTE * ip, ControllerStackInfo* info, TailCallFunctionType type )
57935798{
57945799 MethodDesc* pTailCallDispatcherMD = TailCallHelp::GetTailCallDispatcherMD ();
5795- if (pTailCallDispatcherMD == NULL )
5800+ if (pTailCallDispatcherMD == NULL && type == TailCallFunctionType::TailCallThatReturns )
57965801 {
57975802 return false ;
57985803 }
@@ -5808,6 +5813,11 @@ static bool IsTailCallThatReturns(const BYTE * ip, ControllerStackInfo* info)
58085813 ? trace.GetMethodDesc ()
58095814 : g_pEEInterface->GetNativeCodeMethodDesc (trace.GetAddress ());
58105815
5816+ if (type == TailCallFunctionType::StoreTailCallArgs)
5817+ {
5818+ return (pTargetMD->IsDynamicMethod () && pTargetMD->AsDynamicMethodDesc ()->GetILStubType () == DynamicMethodDesc::StubTailCallStoreArgs);
5819+ }
5820+
58115821 if (pTargetMD != pTailCallDispatcherMD)
58125822 {
58135823 return false ;
@@ -6039,6 +6049,13 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
60396049 fCallingIntoFunclet = IsAddrWithinMethodIncludingFunclet (ji, info->m_activeFrame .md , walker.GetNextIP ()) &&
60406050 ((CORDB_ADDRESS )(SIZE_T )walker.GetNextIP () != ji->m_addrOfCode );
60416051#endif
6052+ // If we are stepping into a tail call that uses the StoreTailCallArgs
6053+ // we need to enable the method enter, otherwise it will behave like a resume
6054+ if (in && IsTailCall (walker.GetNextIP (), info, TailCallFunctionType::StoreTailCallArgs))
6055+ {
6056+ EnableMethodEnter ();
6057+ return true ;
6058+ }
60426059 // At this point, we know that the call/branch target is not
60436060 // in the current method. The possible cases is that this is
60446061 // a jump or a tailcall-via-helper. There are two separate
@@ -6050,7 +6067,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
60506067 // is done by stepping out to the previous user function
60516068 // (non IL stub).
60526069 if ((fIsJump && !fCallingIntoFunclet ) || IsTailCallJitHelper (walker.GetNextIP ()) ||
6053- IsTailCallThatReturns (walker.GetNextIP (), info))
6070+ IsTailCall (walker.GetNextIP (), info, TailCallFunctionType::TailCallThatReturns ))
60546071 {
60556072 // A step-over becomes a step-out for a tail call.
60566073 if (!in)
@@ -6196,7 +6213,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
61966213 return true ;
61976214 }
61986215
6199- if (IsTailCallJitHelper (walker.GetNextIP ()) || IsTailCallThatReturns (walker.GetNextIP (), info))
6216+ if (IsTailCallJitHelper (walker.GetNextIP ()) || IsTailCall (walker.GetNextIP (), info, TailCallFunctionType::TailCallThatReturns ))
62006217 {
62016218 if (!in)
62026219 {
0 commit comments