Skip to content

Commit bd5a164

Browse files
tommcdonCopilot
andauthored
Fix x86 runtime async frame pointer mismatch in GetSpForDiagnosticReporting (#126717)
For certain runtime async frames this resulted in the `ICorDebugManagedCallback2::Exception` to return a null `ICorDebugFrame` for `DEBUG_EXCEPTION_CATCH_HANDLER_FOUND` notifications. The fix addresses this by adjusting `GetSpForDiagnosticReporting` to account for runtime async variant method stack layout differences on x86. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent fa5f840 commit bd5a164

1 file changed

Lines changed: 26 additions & 5 deletions

File tree

src/coreclr/debug/di/rsthread.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,13 +1412,13 @@ HRESULT CordbThread::FindFrame(ICorDebugFrame ** ppFrame, FramePointer fp)
14121412
ICorDebugFrame * pIFrame = pSSW->GetFrame(i);
14131413
CordbFrame * pCFrame = CordbFrame::GetCordbFrameFromInterface(pIFrame);
14141414

1415-
#if defined(HOST_64BIT)
1416-
// On 64-bit we can simply compare the FramePointer.
1415+
#if !defined(TARGET_X86)
1416+
// Compare the FramePointer to determine if the frame matches
14171417
if (pCFrame->GetFramePointer() == fp)
1418-
#else // !HOST_64BIT
1419-
// On other platforms, we need to do a more elaborate check.
1418+
#else
1419+
// On x86 we need to do a more elaborate check. The reason is that on x86, the FramePointer is always the same as the value of EBP, so we can just check if the input FramePointer is contained in the frame. However, on other platforms, the FramePointer may not be the same as the value of RSP, so we need to check if the input FramePointer is the same as the one of the frame.
14201420
if (pCFrame->IsContainedInFrame(fp))
1421-
#endif // HOST_64BIT
1421+
#endif
14221422
{
14231423
*ppFrame = pIFrame;
14241424
(*ppFrame)->AddRef();
@@ -4773,6 +4773,27 @@ bool CordbFrame::IsContainedInFrame(FramePointer fp)
47734773

47744774
CORDB_ADDRESS sp = PTR_TO_CORDB_ADDRESS(fp.GetSPValue());
47754775

4776+
#if defined(TARGET_X86)
4777+
// On x86, the runtime sends CallerSP - sizeof(TADDR) as the frame pointer
4778+
// for exception notifications (see GetSpForDiagnosticReporting). Since this
4779+
// does not account for the stack parameter size, we adjust for it here.
4780+
if (sp > stackEnd)
4781+
{
4782+
CordbNativeFrame * pNativeFrame = GetAsNativeFrame();
4783+
if (pNativeFrame != NULL)
4784+
{
4785+
CORDB_ADDRESS codeAddr = pNativeFrame->GetNativeCode()->GetAddress();
4786+
ULONG32 stackParamSize = 0;
4787+
IDacDbiInterface * pDAC = GetProcess()->GetDAC();
4788+
if (SUCCEEDED(pDAC->GetStackParameterSize(codeAddr + m_ip, &stackParamSize))
4789+
&& stackParamSize > 0)
4790+
{
4791+
sp -= stackParamSize;
4792+
}
4793+
}
4794+
}
4795+
#endif // TARGET_X86
4796+
47764797
if ((stackStart <= sp) && (sp <= stackEnd))
47774798
{
47784799
return true;

0 commit comments

Comments
 (0)