Skip to content

Conversation

@meg-gupta
Copy link
Contributor

@meg-gupta meg-gupta commented Jan 11, 2018

Fixes OS#15078638

When we bailout executing trycode from within OP_TryCatch, we complete the execution of the current function enclosing the try/catch in the interpreter.
If there was an exception within the try region, it is caught and handled accordingly in ProcessTryHandlerBailOut which reconstructs try/catch/finally frames
when we bailout midway executing code within OP_TryCatch. If there was an exception outside the try region, the catch of the OP_TryCatch ends up catching it,
because it happens to be on the callstack. For this we use the hasBailOut bit which is per function, so we know that this exception has to be passed above.

When we have inlined functions inside the try, and for bailouts inside the inlined code, we do not set the hasBailedOut bit, so that the enclosing functions catch in OP_TryCatch catches it.

But when we bailout from inlined code inside try, we execute inlined code, as well as the enclosing function's code in the interpreter.
We will be execution code past the try/catch of the current function in the interpreter. Now if any code outside the eh region throws,
we will catch that in OP_TryCatch which happens to be on the callstack. And we will end up handling it instead of passing above because we have not set the hasBailedOutBit from the bailout point.

This change fixes this issue. We pass a pointer to the hasBailedOutBit and set it once we have finished executing the inlined frames and are ready to process the interpreter frame of the current function.

@meg-gupta meg-gupta force-pushed the fixCatchEatingUpEx branch 2 times, most recently from a3b84f6 to 22f4fa4 Compare January 11, 2018 21:34
@meg-gupta meg-gupta requested review from LouisLaf and rajatd January 11, 2018 21:35
Copy link
Contributor

@rajatd rajatd left a comment

Choose a reason for hiding this comment

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

Another way to fix the problem could be to set hasBailedOut when we return after interpreting the outermost inlinee to the bailout helper code. Of course, we'll have to pass in the offset for hasBailedOut and that could probably be tricky. How does that sound?

@meg-gupta
Copy link
Contributor Author

meg-gupta commented Jan 12, 2018

I tried it out - looks much better now.

@meg-gupta
Copy link
Contributor Author

FYI, both approaches will not work as is once we start inlining functions within try/catch/finally.

@rajatd
Copy link
Contributor

rajatd commented Jan 12, 2018

Hmm, yes, unfortunately

@meg-gupta
Copy link
Contributor Author

@Penguinwizzard @agarwal-sandeep Can you help review this PR ?

StackProber * stackProber;
bool isThreadBound;
bool hasThrownPendingException;
bool * hasBailedOutBitOffset;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: This naming is slightly off, I feel, as this isn't really an offset, but is a full-fledged pointer. This becomes more of an issue in cases like https://github.com/Microsoft/ChakraCore/pull/4535/files#diff-b1ac070605da21777f9c4d31b69a2014R162, where you're setting it with a pointer plus an actual offset.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

{
private:
void * m_prevTryCatchFrameAddr;
bool m_prevDoneBailOutEhRegion;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: is this used in the current version of the changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, removed it. Thanks for catching this.

@meg-gupta meg-gupta force-pushed the fixCatchEatingUpEx branch 2 times, most recently from 00221a3 to cdca4eb Compare January 17, 2018 00:17
Fixes OS#15078638

When we bailout executing trycode from within OP_TryCatch, we complete the execution of the current function enclosing the try/catch in the interpreter.
If there was an exception within the try region, it is caught and handled accordingly in ProcessTryHandlerBailOut which reconstructs try/catch/finally frames
when we bailout midway executing code within OP_TryCatch. If there was an exception outside the try region, the catch of the OP_TryCatch ends up catching it,
because it happens to be on the callstack. For this we use the hasBailOut bit which is per function, so we know that this exception has to be passed above.

When we have inlined functions inside the try, and for bailouts inside the inlined code, we do not set the hasBailedOut bit, so that the enclosing functions catch in OP_TryCatch catches it.

But when we bailout from inlined code inside try, we execute inlined code, as well as the enclosing function's code in the interpreter.
We will be execution code past the try/catch of the current function in the interpreter. Now if any code outside the eh region throws,
we will catch that in OP_TryCatch which happens to be on the callstack. And we will end up handling it instead of passing above because we have not set the hasBailedOutBit from the bailout point.

This change fixes this issue. We pass a pointer to the hasBailedOutBit and set it once we have finished executing the inlined frames and are ready to process the interpreter frame of the current function.
@chakrabot chakrabot merged commit dee125d into chakra-core:release/1.8 Jan 17, 2018
chakrabot pushed a commit that referenced this pull request Jan 17, 2018
…d functions in try/catch

Merge pull request #4535 from meg-gupta:fixCatchEatingUpEx

Fixes OS#15078638

When we bailout executing trycode from within OP_TryCatch, we complete the execution of the current function enclosing the try/catch in the interpreter.
If there was an exception within the try region, it is caught and handled accordingly in ProcessTryHandlerBailOut which reconstructs try/catch/finally frames
when we bailout midway executing code within OP_TryCatch. If there was an exception outside the try region, the catch of the OP_TryCatch ends up catching it,
because it happens to be on the callstack. For this we use the hasBailOut bit which is per function, so we know that this exception has to be passed above.

When we have inlined functions inside the try, and for bailouts inside the inlined code, we do not set the hasBailedOut bit, so that the enclosing functions catch in OP_TryCatch catches it.

But when we bailout from inlined code inside try, we execute inlined code, as well as the enclosing function's code in the interpreter.
We will be execution code past the try/catch of the current function in the interpreter. Now if any code outside the eh region throws,
we will catch that in OP_TryCatch which happens to be on the callstack. And we will end up handling it instead of passing above because we have not set the hasBailedOutBit from the bailout point.

This change fixes this issue. We pass a pointer to the hasBailedOutBit and set it once we have finished executing the inlined frames and are ready to process the interpreter frame of the current function.
chakrabot pushed a commit that referenced this pull request Jan 17, 2018
…are inlined functions in try/catch

Merge pull request #4535 from meg-gupta:fixCatchEatingUpEx

Fixes OS#15078638

When we bailout executing trycode from within OP_TryCatch, we complete the execution of the current function enclosing the try/catch in the interpreter.
If there was an exception within the try region, it is caught and handled accordingly in ProcessTryHandlerBailOut which reconstructs try/catch/finally frames
when we bailout midway executing code within OP_TryCatch. If there was an exception outside the try region, the catch of the OP_TryCatch ends up catching it,
because it happens to be on the callstack. For this we use the hasBailOut bit which is per function, so we know that this exception has to be passed above.

When we have inlined functions inside the try, and for bailouts inside the inlined code, we do not set the hasBailedOut bit, so that the enclosing functions catch in OP_TryCatch catches it.

But when we bailout from inlined code inside try, we execute inlined code, as well as the enclosing function's code in the interpreter.
We will be execution code past the try/catch of the current function in the interpreter. Now if any code outside the eh region throws,
we will catch that in OP_TryCatch which happens to be on the callstack. And we will end up handling it instead of passing above because we have not set the hasBailedOutBit from the bailout point.

This change fixes this issue. We pass a pointer to the hasBailedOutBit and set it once we have finished executing the inlined frames and are ready to process the interpreter frame of the current function.
chakrabot pushed a commit that referenced this pull request Jan 17, 2018
…t when there are inlined functions in try/catch

Merge pull request #4535 from meg-gupta:fixCatchEatingUpEx

Fixes OS#15078638

When we bailout executing trycode from within OP_TryCatch, we complete the execution of the current function enclosing the try/catch in the interpreter.
If there was an exception within the try region, it is caught and handled accordingly in ProcessTryHandlerBailOut which reconstructs try/catch/finally frames
when we bailout midway executing code within OP_TryCatch. If there was an exception outside the try region, the catch of the OP_TryCatch ends up catching it,
because it happens to be on the callstack. For this we use the hasBailOut bit which is per function, so we know that this exception has to be passed above.

When we have inlined functions inside the try, and for bailouts inside the inlined code, we do not set the hasBailedOut bit, so that the enclosing functions catch in OP_TryCatch catches it.

But when we bailout from inlined code inside try, we execute inlined code, as well as the enclosing function's code in the interpreter.
We will be execution code past the try/catch of the current function in the interpreter. Now if any code outside the eh region throws,
we will catch that in OP_TryCatch which happens to be on the callstack. And we will end up handling it instead of passing above because we have not set the hasBailedOutBit from the bailout point.

This change fixes this issue. We pass a pointer to the hasBailedOutBit and set it once we have finished executing the inlined frames and are ready to process the interpreter frame of the current function.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants