This bug fix is a port from the equivalent fix in framework. The
debugger tried performing a stackwalk in the epilog due to the JIT
incorrectly reporting epilogue information. This caused an invalid
GS cookie to be checked and caused the debugger to crash. A flag was
added to allow debug stackwalks to skip the cookie check.
Commit migrated from https://github.com/dotnet/coreclr/commit/
32741b9e97f901242394dfc682c228a5d810f454
mCurr = &mHead;
// Walk the stack, set mEnumerated to true to ensure we don't do it again.
- unsigned int flagsStackWalk = ALLOW_INVALID_OBJECTS|ALLOW_ASYNC_STACK_WALK;
+ unsigned int flagsStackWalk = ALLOW_INVALID_OBJECTS|ALLOW_ASYNC_STACK_WALK|SKIP_GSCOOKIE_CHECK;
#if defined(WIN64EXCEPTIONS)
flagsStackWalk |= GC_FUNCLET_REFERENCE_REPORTING;
#endif // defined(WIN64EXCEPTIONS)
Debugger::AtSafePlaceStackWalkCallback,
(VOID*)(&atSafePlace),
QUICKUNWIND | HANDLESKIPPEDFRAMES |
- DISABLE_MISSING_FRAME_DETECTION);
+ DISABLE_MISSING_FRAME_DETECTION | SKIP_GSCOOKIE_CHECK);
#ifdef LOGGING
if (!atSafePlace)
result = g_pEEInterface->StackWalkFramesEx(thread, &data.regDisplay,
DebuggerWalkStackProc,
- &data, flags | HANDLESKIPPEDFRAMES | NOTIFY_ON_U2M_TRANSITIONS | ALLOW_ASYNC_STACK_WALK);
+ &data,
+ flags | HANDLESKIPPEDFRAMES | NOTIFY_ON_U2M_TRANSITIONS |
+ ALLOW_ASYNC_STACK_WALK | SKIP_GSCOOKIE_CHECK);
}
else
{
}
INDEBUG(m_pRealStartFrame = m_crawl.pFrame);
- if (m_crawl.pFrame != FRAME_TOP)
+ if (m_crawl.pFrame != FRAME_TOP && !(m_flags & SKIP_GSCOOKIE_CHECK))
{
m_crawl.SetCurGSCookie(Frame::SafeGetGSCookiePtr(m_crawl.pFrame));
}
_ASSERTE(m_crawl.pFrame != NULL);
}
- if (m_crawl.pFrame != FRAME_TOP)
+ if (m_crawl.pFrame != FRAME_TOP && !(m_flags & SKIP_GSCOOKIE_CHECK))
{
m_crawl.SetCurGSCookie(Frame::SafeGetGSCookiePtr(m_crawl.pFrame));
}
&m_crawl.codeManState);
#endif // !DACCESS_COMPILE
- if (m_pCachedGSCookie)
+ if (!(m_flags & SKIP_GSCOOKIE_CHECK) && m_pCachedGSCookie)
{
m_crawl.SetCurGSCookie(m_pCachedGSCookie);
}
// Refer to StackFrameIterator::Filter for detailed comments on this flag.
#define GC_FUNCLET_REFERENCE_REPORTING 0x8000
+ // Stackwalking normally checks GS cookies on the fly, but there are cases in which the JIT reports
+ // incorrect epilog information. This causes the debugger to request stack walks in the epilog, checking
+ // an now invalid cookie. This flag allows the debugger stack walks to disable GS cookie checking.
+
+ // This is a workaround for the debugger stackwalking. In general, the stackwalker and CrawlFrame
+ // may still execute GS cookie tracking/checking code paths.
+ #define SKIP_GSCOOKIE_CHECK 0x10000
+
StackWalkAction StackWalkFramesEx(
PREGDISPLAY pRD, // virtual register set at crawl start
PSTACKWALKFRAMESCALLBACK pCallback,