-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Fix collided unwind detection #121625
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 collided unwind detection #121625
Conversation
A recent fix that has moved 2nd pass of the exception handling to native code has accidentally broken detectin of collided unwind, that means detection of when exception escapes a catch or exceptionally called finally funclets. Unfortunately none of our coreclr and libraries test exercise the specific case when the problem occurs, which is as follows: * There is a try / catch inside of an outer catch * The try block contains try / finally and the non-exceptionally called finally throws. In this case, the stack walk out of the throwing finally funclet was incorrectly classifed as an exception collision and the catch was skipped. The problem was that the last part of the condition to detect the collided unwind was wrong. In fact, it was always true, so any unwind out of a funclet was considered to be a collision even if the funclet was a finally that was called non-exceptionally. This change fixes it by identifying the collision by the fact that the stack walker has moved from a funclet to native code, which is the only case when the exception is really escaping an exceptionally called funclet. I have also added a regression test for the issue. Close dotnet#121578
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.
Pull Request Overview
This PR fixes a bug in collided unwind detection during exception handling. A collided unwind occurs when an exception escapes from a catch or exceptionally-called finally funclet. The bug caused incorrect behavior when a non-exceptionally called finally throws an exception inside an outer catch block - the runtime incorrectly classified this as a collision and skipped the catch clause.
Key Changes:
- Modified the collided unwind detection condition in
exceptionhandling.cppto correctly identify collisions only when transitioning from a funclet to native code - Added regression test
test121578.csthat exercises the specific scenario: try/catch with nested try/finally where the non-exceptionally called finally throws
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/coreclr/vm/exceptionhandling.cpp | Changed collided unwind detection condition to check frame state instead of stack pointer comparison |
| src/tests/Regressions/coreclr/GitHub_121578/test121578.csproj | Project file for new regression test |
| src/tests/Regressions/coreclr/GitHub_121578/test121578.cs | Regression test that reproduces the bug scenario |
Co-authored-by: Copilot <[email protected]>
|
/backport to release/10.0 |
|
Started backporting to |
|
/azp run runtime-coreclr outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/ba-g the failing outerloop tests are unrelated to the change - those are SVE numeric omputations failures - #121659 |
A recent fix that has moved 2nd pass of the exception handling to native
code has accidentally broken detectin of collided unwind, that means
detection of when exception escapes a catch or exceptionally called finally
funclets. Unfortunately none of our coreclr and libraries test exercise
the specific case when the problem occurs, which is as follows:
finally throws.
In this case, the stack walk out of the throwing finally funclet was
incorrectly classifed as an exception collision and the catch was
skipped.
The problem was that the last part of the condition to detect the collided
unwind was wrong. In fact, it was always true, so any unwind out of a
funclet was considered to be a collision even if the funclet was a
finally that was called non-exceptionally.
This change fixes it by identifying the collision by the fact that the
stack walker has moved from a funclet to native code, which is the only
case when the exception is really escaping an exceptionally called
funclet.
I have also added a regression test for the issue.
Close #121578