-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Fix x86 InlinedCallFrame popping during EH #2215
Conversation
src/coreclr/src/vm/i386/excepx86.cpp
Outdated
{ | ||
// The current explicit frame is below the resume esp and it is an inlined call frame with an active call. | ||
// |
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.
Nit: You can fix typos in the comment below while you are on it:
unlined
pinovoke
src/coreclr/src/vm/i386/excepx86.cpp
Outdated
@@ -1868,8 +1868,10 @@ NOINLINE LPVOID COMPlusEndCatchWorker(Thread * pThread) | |||
// Sync managed exception state, for the managed thread, based upon any active exception tracker | |||
pThread->SyncManagedExceptionState(fIsDebuggerHelperThread); | |||
|
|||
if (InlinedCallFrame::FrameHasActiveCall(pThread->m_pFrame)) | |||
if ((pThread->m_pFrame < esp) && InlinedCallFrame::FrameHasActiveCall(pThread->m_pFrame)) |
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.
How does this work?
I believe that we need to check whether the frame is within the method that we are resuming into, ie we need to check whether pFrame < callerESP
.
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.
Hmm, you are right that this would not work for the case when the location we resume to is in the same function as the pinvoke frame. It works when it is anywhere up the call chain.
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.
Could you please also delete the workaround for this bug from AssemblyNative::InternalLoad ? |
There is a bug in InlinedCallFrame popping on x86 during EH with R2R compiled code. The code is popping this frame if it is at the top of the explicit frames stack before executing catch handler. But it is missing a check to see if the frame was actually in the unwound part of the stack. So in some corner cases, it can end up popping a frame that belongs to an active pinvoke somewhere up the call chain. The fix is to do the popping only if the InlinedCallFrame is located at an address smaller than the resume ESP.
The correct ESP to use for detecting the InlinedCallFrame affected by the current exception handling is the the ESP of the caller of the method that contains the exception handler. I have moved the check to a different location where the CrawlFrame with the context of the exception handler is still available and we can unwind it to get the caller's SP.
7c32f98
to
54720ec
Compare
@jkotas I've removed the workaround for the issue, can you please take a look again? |
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.
Thanks!
There is a bug in InlinedCallFrame popping on x86 during EH with R2R
compiled code. The code is popping this frame if it is at the top of
the explicit frames stack before executing catch handler. But it
is missing a check to see if the frame was actually in the unwound part
of the stack. So in some corner cases, it can end up popping a frame
that belongs to an active pinvoke somewhere up the call chain.
The fix is to do the popping only if the InlinedCallFrame is located at
an address smaller than the resume ESP.
Close #2240