You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix interpreter EH when exception escapes filter funclet (#120811)
The EH was crashing with interpreter when there was an unhandled
exception in a filter funclet. It was asserting on x64 windows due to
SSP not being correct, but the actual issue was more involved than just
ensuring the SSP was correct.
The problem happens due to the way the stack walking handles unwinding
from the first interpreted frame. To better explain what was wrong, let
me describe hat mechanism. That transition sets the IP to a special
value InterpreterFrame::DummyCallerIP and SP to the address of the
InterpreterFrame. The frame state is SFITER_NATIVE_MARKER_FRAME. When
the stack frame iterator moves to the next frame, the state is
SFITER_FRAME_FUNCTION, the explicit frame is the InterpreterFrame and
the REGDISPLAY is set to the native context that was in REGDISPLAY
before we switched to iterating over the interpreter frames.
The SfiNext in the EH needs to handle the case when it gets the
SFITER_NATIVE_MARKER_FRAME described above. It can either be
transitioning to a managed caller of the interpreted core or it could
have been a call to a funclet that doesn't have transition frame stored
in the intepreter frame, so it doesn't have any context to move to. This
doesn't cause any problem for catch or finally funclets, as that means a
collided unwind that is detected and the REGDISPLAY is overwritten by
the REGDISPLAY from the stack frame iterator of the exception that we've
collided with.
The only problem is for filter funclet, where we need to return that
frame from the SfiNext and the EH uses its SP in the second pass to know
when the 2nd pass is finished.
The bug was that we have moved the stack frame iterator from the
SFITER_NATIVE_MARKER_FRAME, which got REGDISPLAY with SP that was
actually smaller than the SP of the last reported interpreted frame.
That caused the 2nd pass to terminate prematurely on the very first
frame, thinking it found the target frame. Thus finallys were not called
and also the context was wrong. That lead to the assert in
CallCatchFunclet.
There was also a secondary problem that we were not saving and restoring
SSP when the state moved from the special state with IP set to
InterpreterFrame::DummyCallerIP and the SSP was the SSP in the
InterpExecMethod, instead of the SSP in the DispatchManagedException
that the rest of the context was pointing to.
This change fixes both these issues and unhandled exceptions in filter
funclets are correctly swallowed now.
0 commit comments