@@ -92,7 +92,18 @@ StackFrameIterator::StackFrameIterator(Thread * pThreadToWalk, PInvokeTransition
92
92
{
93
93
STRESS_LOG0 (LF_STACKWALK, LL_INFO10000, " ----Init---- [ GC ]\n " );
94
94
ASSERT (!pThreadToWalk->DangerousCrossThreadIsHijacked ());
95
- InternalInit (pThreadToWalk, pInitialTransitionFrame, GcStackWalkFlags);
95
+
96
+ #ifdef FEATURE_SUSPEND_REDIRECTION
97
+ if (pInitialTransitionFrame == REDIRECTED_THREAD_MARKER)
98
+ {
99
+ InternalInit (pThreadToWalk, pThreadToWalk->GetRedirectionContext (), GcStackWalkFlags | ActiveStackFrame);
100
+ }
101
+ else
102
+ #endif
103
+ {
104
+ InternalInit (pThreadToWalk, pInitialTransitionFrame, GcStackWalkFlags);
105
+ }
106
+
96
107
PrepareToYieldFrame ();
97
108
}
98
109
@@ -497,6 +508,112 @@ void StackFrameIterator::InternalInit(Thread * pThreadToWalk, PTR_PAL_LIMITED_CO
497
508
#endif // TARGET_ARM
498
509
}
499
510
511
+ // Prepare to start a stack walk from the context listed in the supplied CONTEXT.
512
+ // The supplied context can describe a location in either managed or unmanaged code. In the
513
+ // latter case the iterator is left in an invalid state when this function returns.
514
+ void StackFrameIterator::InternalInit (Thread * pThreadToWalk, CONTEXT* pCtx, uint32_t dwFlags)
515
+ {
516
+ ASSERT ((dwFlags & MethodStateCalculated) == 0 );
517
+
518
+ EnterInitialInvalidState (pThreadToWalk);
519
+
520
+ m_dwFlags = dwFlags;
521
+
522
+ // We need to walk the ExInfo chain in parallel with the stackwalk so that we know when we cross over
523
+ // exception throw points. So we must find our initial point in the ExInfo chain here so that we can
524
+ // properly walk it in parallel.
525
+ ResetNextExInfoForSP (pCtx->GetSp ());
526
+
527
+ // This codepath is used by the hijack stackwalk and we can get arbitrary ControlPCs from there. If this
528
+ // context has a non-managed control PC, then we're done.
529
+ if (!m_pInstance->IsManaged (dac_cast<PTR_VOID>(pCtx->GetIp ())))
530
+ return ;
531
+
532
+ //
533
+ // control state
534
+ //
535
+ SetControlPC (dac_cast<PTR_VOID>(pCtx->GetIp ()));
536
+ m_RegDisplay.SP = pCtx->GetSp ();
537
+ m_RegDisplay.IP = pCtx->GetIp ();
538
+
539
+ #ifdef TARGET_ARM64
540
+
541
+ m_RegDisplay.pIP = PTR_TO_MEMBER (CONTEXT, pCtx, Pc);
542
+
543
+ //
544
+ // preserved regs
545
+ //
546
+ m_RegDisplay.pX19 = PTR_TO_MEMBER (CONTEXT, pCtx, X19);
547
+ m_RegDisplay.pX20 = PTR_TO_MEMBER (CONTEXT, pCtx, X20);
548
+ m_RegDisplay.pX21 = PTR_TO_MEMBER (CONTEXT, pCtx, X21);
549
+ m_RegDisplay.pX22 = PTR_TO_MEMBER (CONTEXT, pCtx, X22);
550
+ m_RegDisplay.pX23 = PTR_TO_MEMBER (CONTEXT, pCtx, X23);
551
+ m_RegDisplay.pX24 = PTR_TO_MEMBER (CONTEXT, pCtx, X24);
552
+ m_RegDisplay.pX25 = PTR_TO_MEMBER (CONTEXT, pCtx, X25);
553
+ m_RegDisplay.pX26 = PTR_TO_MEMBER (CONTEXT, pCtx, X26);
554
+ m_RegDisplay.pX27 = PTR_TO_MEMBER (CONTEXT, pCtx, X27);
555
+ m_RegDisplay.pX28 = PTR_TO_MEMBER (CONTEXT, pCtx, X28);
556
+ m_RegDisplay.pFP = PTR_TO_MEMBER (CONTEXT, pCtx, Fp);
557
+ m_RegDisplay.pLR = PTR_TO_MEMBER (CONTEXT, pCtx, Lr);
558
+
559
+ //
560
+ // scratch regs
561
+ //
562
+ m_RegDisplay.pX0 = PTR_TO_MEMBER (CONTEXT, pCtx, X0);
563
+ m_RegDisplay.pX1 = PTR_TO_MEMBER (CONTEXT, pCtx, X1);
564
+ m_RegDisplay.pX2 = PTR_TO_MEMBER (CONTEXT, pCtx, X2);
565
+ m_RegDisplay.pX3 = PTR_TO_MEMBER (CONTEXT, pCtx, X3);
566
+ m_RegDisplay.pX4 = PTR_TO_MEMBER (CONTEXT, pCtx, X4);
567
+ m_RegDisplay.pX5 = PTR_TO_MEMBER (CONTEXT, pCtx, X5);
568
+ m_RegDisplay.pX6 = PTR_TO_MEMBER (CONTEXT, pCtx, X6);
569
+ m_RegDisplay.pX7 = PTR_TO_MEMBER (CONTEXT, pCtx, X7);
570
+ m_RegDisplay.pX8 = PTR_TO_MEMBER (CONTEXT, pCtx, X8);
571
+ m_RegDisplay.pX9 = PTR_TO_MEMBER (CONTEXT, pCtx, X9);
572
+ m_RegDisplay.pX10 = PTR_TO_MEMBER (CONTEXT, pCtx, X10);
573
+ m_RegDisplay.pX11 = PTR_TO_MEMBER (CONTEXT, pCtx, X11);
574
+ m_RegDisplay.pX12 = PTR_TO_MEMBER (CONTEXT, pCtx, X12);
575
+ m_RegDisplay.pX13 = PTR_TO_MEMBER (CONTEXT, pCtx, X13);
576
+ m_RegDisplay.pX14 = PTR_TO_MEMBER (CONTEXT, pCtx, X14);
577
+ m_RegDisplay.pX15 = PTR_TO_MEMBER (CONTEXT, pCtx, X15);
578
+ m_RegDisplay.pX16 = PTR_TO_MEMBER (CONTEXT, pCtx, X16);
579
+ m_RegDisplay.pX17 = PTR_TO_MEMBER (CONTEXT, pCtx, X17);
580
+ m_RegDisplay.pX18 = PTR_TO_MEMBER (CONTEXT, pCtx, X18);
581
+
582
+ #elif defined(TARGET_X86) || defined(TARGET_AMD64)
583
+
584
+ m_RegDisplay.pIP = (PTR_PCODE)PTR_TO_MEMBER (CONTEXT, pCtx, Rip);
585
+
586
+ //
587
+ // preserved regs
588
+ //
589
+ m_RegDisplay.pRbp = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, Rbp);
590
+ m_RegDisplay.pRsi = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, Rsi);
591
+ m_RegDisplay.pRdi = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, Rdi);
592
+ m_RegDisplay.pRbx = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, Rbx);
593
+ #ifdef TARGET_AMD64
594
+ m_RegDisplay.pR12 = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, R12);
595
+ m_RegDisplay.pR13 = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, R13);
596
+ m_RegDisplay.pR14 = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, R14);
597
+ m_RegDisplay.pR15 = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, R15);
598
+ #endif // TARGET_AMD64
599
+
600
+ //
601
+ // scratch regs
602
+ //
603
+ m_RegDisplay.pRax = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, Rax);
604
+ m_RegDisplay.pRcx = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, Rcx);
605
+ m_RegDisplay.pRdx = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, Rdx);
606
+ #ifdef TARGET_AMD64
607
+ m_RegDisplay.pR8 = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, R8);
608
+ m_RegDisplay.pR9 = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, R9);
609
+ m_RegDisplay.pR10 = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, R10);
610
+ m_RegDisplay.pR11 = (PTR_UIntNative)PTR_TO_MEMBER (CONTEXT, pCtx, R11);
611
+ #endif // TARGET_AMD64
612
+ #else
613
+ PORTABILITY_ASSERT (" StackFrameIterator::InternalInit" );
614
+ #endif // TARGET_ARM
615
+ }
616
+
500
617
PTR_VOID StackFrameIterator::HandleExCollide (PTR_ExInfo pExInfo)
501
618
{
502
619
STRESS_LOG3 (LF_STACKWALK, LL_INFO10000, " [ ex collide ] kind = %d, pass = %d, idxCurClause = %d\n " ,
@@ -1290,7 +1407,7 @@ void StackFrameIterator::NextInternal()
1290
1407
{
1291
1408
UnwindOutOfCurrentManagedFrame:
1292
1409
ASSERT (m_dwFlags & MethodStateCalculated);
1293
- m_dwFlags &= ~(ExCollide|MethodStateCalculated|UnwoundReversePInvoke);
1410
+ m_dwFlags &= ~(ExCollide|MethodStateCalculated|UnwoundReversePInvoke|ActiveStackFrame );
1294
1411
ASSERT (IsValid ());
1295
1412
1296
1413
m_pHijackedReturnValue = NULL ;
@@ -1640,6 +1757,12 @@ MethodInfo * StackFrameIterator::GetMethodInfo()
1640
1757
return &m_methodInfo;
1641
1758
}
1642
1759
1760
+ bool StackFrameIterator::IsActiveStackFrame ()
1761
+ {
1762
+ ASSERT (IsValid ());
1763
+ return (m_dwFlags & ActiveStackFrame) != 0 ;
1764
+ }
1765
+
1643
1766
#ifdef DACCESS_COMPILE
1644
1767
#define FAILFAST_OR_DAC_RETURN_FALSE (x ) if (!(x)) return false ;
1645
1768
#else
0 commit comments