-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Fix x86 EH for UnmanagedCallersOnly methods #58796
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
Conversation
There is a bug in the exception handling on x86 when exception is propagated from a method marked with UnmanagedCallersOnly attribute to an immediate caller that's also managed (and calls the method via a native delegate). In this case, there is no native frame in between and the stack walker accidentally skips the InlinedCallFrame processing during first pass of exception handling. The InlinedCallFrame is expected to be processed before the related PInvoke IL stub and it doesn't happen in this case, as a native frame is required to make the stack frame iterator move to the explicit InlinedCallFrame. The fact that it is not processed results in ignoring the upper limit on the stack walk and walking the stack further than expected. This change fixes it by detecting the direct transition from UnmanagedCallersOnly to managed caller and forces the stack frame iterator to process the InlinedCallFrame.
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
62f65f1
to
36861ee
Compare
@@ -3135,6 +3137,12 @@ void StackFrameIterator::PostProcessingForManagedFrames(void) | |||
m_exInfoWalk.WalkToPosition(GetRegdisplaySP(m_crawl.pRD), (m_flags & POPFRAMES)); | |||
#endif // ELIMINATE_FEF | |||
|
|||
#ifdef TARGET_X86 | |||
hdrInfo gcHdrInfo; | |||
DecodeGCHdrInfo(m_crawl.codeInfo.GetGCInfoToken(), 0, &gcHdrInfo); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All other places that decode GCInfo in this file go through m_crawl.GetCodeManager()
. Is it worth following the pattern?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, but let me do that as a separate cleanup so that this change is just a fix for the bug. I will need to add a new method to the EECodeManager and then I'd use it in the exceptionhandling.cpp too where we currently also have this raw decoding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There is a bug in the exception handling on x86 when exception is
propagated from a method marked with UnmanagedCallersOnly attribute to
an immediate caller that's also managed (and calls the method via a
native delegate). In this case, there is no native frame in between and
the stack walker accidentally skips the InlinedCallFrame processing
during first pass of exception handling. The InlinedCallFrame is expected
to be processed before the related PInvoke IL stub and it doesn't happen
in this case, as a native frame is required to make the stack frame iterator
move to the explicit InlinedCallFrame. The fact that it is not processed
results in ignoring the upper limit on the stack walk and walking the stack
further than expected.
This change fixes it by detecting the direct transition from
UnmanagedCallersOnly to managed caller and forces the stack frame
iterator to process the InlinedCallFrame.
Fixes #57915