@@ -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// -------------------------------------------------------------------------
@@ -5631,10 +5636,10 @@ static bool IsTailCallJitHelper(const BYTE * ip)
56315636// control flow will be a little peculiar in that the function will return
56325637// immediately, so we need special handling in the debugger for it. This
56335638// function detects that case to be used for those scenarios.
5634- static bool IsTailCallThatReturns (const BYTE * ip, ControllerStackInfo* info)
5639+ static bool IsTailCall (const BYTE * ip, ControllerStackInfo* info, TailCallFunctionType type )
56355640{
56365641 MethodDesc* pTailCallDispatcherMD = TailCallHelp::GetTailCallDispatcherMD ();
5637- if (pTailCallDispatcherMD == NULL )
5642+ if (pTailCallDispatcherMD == NULL && type == TailCallFunctionType::TailCallThatReturns )
56385643 {
56395644 return false ;
56405645 }
@@ -5650,6 +5655,11 @@ static bool IsTailCallThatReturns(const BYTE * ip, ControllerStackInfo* info)
56505655 ? trace.GetMethodDesc ()
56515656 : g_pEEInterface->GetNativeCodeMethodDesc (trace.GetAddress ());
56525657
5658+ if (type == TailCallFunctionType::StoreTailCallArgs)
5659+ {
5660+ return (pTargetMD->IsDynamicMethod () && pTargetMD->AsDynamicMethodDesc ()->GetILStubType () == DynamicMethodDesc::StubTailCallStoreArgs);
5661+ }
5662+
56535663 if (pTargetMD != pTailCallDispatcherMD)
56545664 {
56555665 return false ;
@@ -5881,6 +5891,13 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
58815891 fCallingIntoFunclet = IsAddrWithinMethodIncludingFunclet (ji, info->m_activeFrame .md , walker.GetNextIP ()) &&
58825892 ((CORDB_ADDRESS)(SIZE_T)walker.GetNextIP () != ji->m_addrOfCode );
58835893#endif
5894+ // If we are stepping into a tail call that uses the StoreTailCallArgs
5895+ // we need to enable the method enter, otherwise it will behave like a resume
5896+ if (in && IsTailCall (walker.GetNextIP (), info, TailCallFunctionType::StoreTailCallArgs))
5897+ {
5898+ EnableMethodEnter ();
5899+ return true ;
5900+ }
58845901 // At this point, we know that the call/branch target is not
58855902 // in the current method. The possible cases is that this is
58865903 // a jump or a tailcall-via-helper. There are two separate
@@ -5892,7 +5909,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
58925909 // is done by stepping out to the previous user function
58935910 // (non IL stub).
58945911 if ((fIsJump && !fCallingIntoFunclet ) || IsTailCallJitHelper (walker.GetNextIP ()) ||
5895- IsTailCallThatReturns (walker.GetNextIP (), info))
5912+ IsTailCall (walker.GetNextIP (), info, TailCallFunctionType::TailCallThatReturns ))
58965913 {
58975914 // A step-over becomes a step-out for a tail call.
58985915 if (!in)
@@ -6038,7 +6055,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
60386055 return true ;
60396056 }
60406057
6041- if (IsTailCallJitHelper (walker.GetNextIP ()) || IsTailCallThatReturns (walker.GetNextIP (), info))
6058+ if (IsTailCallJitHelper (walker.GetNextIP ()) || IsTailCall (walker.GetNextIP (), info, TailCallFunctionType::TailCallThatReturns ))
60426059 {
60436060 if (!in)
60446061 {
0 commit comments