Skip to content

Fix stackwalk from interpreted EH funclet #116640

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 16, 2025

Conversation

janvorli
Copy link
Member

The stack walking for GC is broken when an interpreted EH funclet was on the stack. The reason is that call to the interpreted funclet doesn't have a transition frame and that case was not handled properly. Also, I have found that the ExInfo::m_csfEHClause was not being set for the interpreted clauses at all.

This change fixes it by using the InterpreterFrame address as the m_csfEHClause (so that it is above all the interpreter frames) and fixing the ExInfo::FindParentStackFrameHelper to recognize the special instruction pointer value that we get as a parent IP for the first interpreted frame under an InterpreterFrame.

That special value has been zero and I have added a named constant for it so that it is clear at the points where it is being used.

The stack walking for GC is broken when an interpreted EH funclet was
on the stack. The reason is that call to the interpreted funclet doesn't
have a transition frame and that case was not handled properly. Also,
I have found that the ExInfo::m_csfEHClause was not being set for the
interpreted clauses at all.

This change fixes it by using the InterpreterFrame address as the
m_csfEHClause (so that it is above all the interpreter frames) and
fixing the `ExInfo::FindParentStackFrameHelper` to recognize the special
instruction pointer value that we get as a parent IP for the first
interpreted frame under an InterpreterFrame.

That special value has been zero and I have added a named constant for
it so that it is clear at the points where it is being used.
@janvorli janvorli added this to the 10.0.0 milestone Jun 13, 2025
@janvorli janvorli self-assigned this Jun 13, 2025
@Copilot Copilot AI review requested due to automatic review settings June 13, 2025 17:05
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes the broken stack walking for GC when an interpreted EH funclet is on the stack by using the InterpreterFrame address as m_csfEHClause and updating the unwinding logic to properly detect the special caller IP value.

  • Defines a special constant (DummyCallerIP) in the InterpreterFrame for clarity.
  • Updates exception handling to recognize DummyCallerIP as a marker of interpreted frames.
  • Adjusts the funclet call and virtual unwind logic to use the new DummyCallerIP value.

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/coreclr/vm/frames.h Added a named constant DummyCallerIP to clarify interpreter frames.
src/coreclr/vm/exceptionhandling.cpp Updated logic to check for DummyCallerIP when walking the stack.
src/coreclr/vm/eetwain.cpp Revised funclet call and unwind handling to use DummyCallerIP.
Comments suppressed due to low confidence (2)

src/coreclr/vm/exceptionhandling.cpp:2790

  • Ensure that sufficient test coverage exists for the new execution path when callerIP equals DummyCallerIP to prevent regression in stack walking behavior.
if (callerIP == InterpreterFrame::DummyCallerIP)

src/coreclr/vm/eetwain.cpp:2446

  • Verify that using GetFirstArgReg(pContext) to obtain the InterpreterFrame address for setting SP yields the expected result; consider adding a clarifying comment if necessary.
SetIP(pContext, InterpreterFrame::DummyCallerIP);

@@ -2784,11 +2784,15 @@ StackFrame ExInfo::FindParentStackFrameHelper(CrawlFrame* pCF,
// Check for out-of-line finally funclets. Filter funclets can't be out-of-line.
if (!fIsFilterFunclet)
{
if (pRegDisplay->IsCallerContextValid)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check was reduntant, we always have the parent frame here. The CallerStackFrame::FromRegDisplay asserts that.

@janvorli janvorli requested a review from jkotas June 13, 2025 17:07
@jkotas
Copy link
Member

jkotas commented Jun 14, 2025

Build breaks look related:

  /__w/1/s/src/coreclr/vm/exceptionhandling.cpp:2790:25: error: use of undeclared identifier 'InterpreterFrame'
   2790 |         if (callerIP == InterpreterFrame::DummyCallerIP)

Update comment

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
@janvorli janvorli merged commit 62fabc3 into dotnet:main Jun 16, 2025
96 checks passed
@janvorli janvorli deleted the fix-stacwalk-from-interpreted-funclet branch June 16, 2025 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants