Repository navigation
[Interpreter] Install the resume-after-catch handler in ThrowControlForThread - #135533
Draft
pcshrosbree wants to merge 3 commits into
Draft
pcshrosbree wants to merge 3 commits into
pcshrosbree wants to merge 3 commits into
Conversation
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
Tagging subscribers to this area: @JulieLeeMSFT, @BrzVlad, @janvorli |
When interpreted code catches a ThreadAbortException, raise the abort again where the execution resumes after the catch, as EECodeManager::ResumeAfterCatch does for compiled code: - Set up Thread::m_OSContext for the resume point before calling COMPlusCheckForAbort, which expects its caller to do that (dotnet#135463). - Dispatch the abort from a try block of its own, outside the C++ catch block for ResumeAfterCatchException, so that the execution can resume again when the abort is caught again in the same InterpExecMethod. - Make the catch leave island the resume point. Within a leave, every edge into a catch leave island uses INTOP_LEAVE_CATCH; every other edge, including the final edge to the leave target, uses INTOP_BR. The catch therefore ends with INTOP_LEAVE_CATCH to its island. The island is inside every try region that encloses the catch's try region. The leave target need not be inside all of those regions (dotnet#135871). - Mark the frame faulting before the dispatch, as INTOP_THROW does, so that the handlers are looked up at the resume IP itself rather than at the instruction before it. Add the test GitHub_135463. Its two dotnet#135871 cases run only when the test is interpreted, because jitted code gets them wrong until dotnet#135637 is fixed. Enable ControlledExecutionTests.CancelInTryAndExitCatchNormally again, and stop skipping test135530 under the interpreter. Fixes dotnet#135463 Fixes dotnet#135871
Remove the goto at the end of the catch of ResumeAfterCatchException, which only jumped to the next statement. Move the block that raises the abort again to just after the resume code, so that a pending abort falls through into it instead of jumping to a label after EXIT_FRAME. No change in behavior.
When compiled code raises a thread abort again at the end of a catch handler and an interpreted frame catches it, the ResumeAfterCatchException that resumes that frame ran into the managed frames ThrowControlForThread was redirected from. Install the handler there, as IL_Throw and HandleManagedFault do. On Windows x64 with shadow stacks, the frame of a redirected thread was interrupted rather than stopped at a call and its recorded SSP is exact, so tell the rethrow not to search for a more precise one. Enable ControlledExecutionTests.CancelItselfOutsideOfTryCatchFinally again and add the scenario to the GitHub_135463 regression test. Fixes dotnet#135532
pcshrosbree
force-pushed
the
interp-abort-throw-control
branch
from
October 16, 2026 19:44
45a66f6 to
bc3b55a
Compare
This was referenced Oct 16, 2026
Open
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #135532.
Draft, stacked on #135939. The first two commits are #135939; only the last commit belongs to this PR. I'll rebase once #135939 is in.
ThrowControlForThreadraises the thread abort that compiled code raises again at the end of a catch handler. Before this change, when an interpreted frame further up caught the abort, theResumeAfterCatchExceptionused to resume that frame encountered the managed frames present when the thread was redirected. NowThrowControlForThreadinstalls the resume-after-catch handler, likeIL_ThrowandHandleManagedFault.On Windows x64 with shadow stacks, the handler's rethrow searched for a "precise" SSP on the assumption that the slot below the SSP holds a return address in the context's frame. A redirected thread's frame was interrupted rather than stopped at a call, and its recorded SSP is exact already, so the search moved it past the correct position. The new
INSTALL_RESUME_AFTER_CATCH_HANDLER_WITH_INTERRUPTED_CONTEXTmarks the context as interrupted, so thatRethrowResumeAfterCatchExceptionSkipManagedFramesuses the recorded SSP without searching for another one. The same mismatch caused #135530, fixed by #135531.Tests: a
CancelItselfscenario insrc/tests/Regressions/coreclr/GitHub_135463(the action cancels its own token), andControlledExecutionTests.CancelItselfOutsideOfTryCatchFinallyenabled again.Validation of the new scenario (Checked; linux-x64, osx-arm64, windows-x64 with CET enabled):
DOTNET_InterpMode=1, with and withoutTieredCompilation=0ResumeAfterCatchException; windows: assertDOTNET_InterpMode2 and 3Additional validation:
TieredCompilation=0,JITMinOpts,JitStress1 and 2,ReadyToRun=0, andGCStress0x3 and 0xC on all three platforms. ItsTestEnclosingTryis skipped under the JIT, as in [Interpreter] Raise a pending thread abort again at the resume point after a catch #135939.ControlledExecutionTestspass when run as a class in one process, andCancelItselfOutsideOfTryCatchFinallyalso passes when run alone in its own process. Both runs pass on all three platforms under the JIT andDOTNET_InterpMode1, 2 and 3.CancelItselfOutsideOfTryCatchFinallyfails under mode 1: it terminates withResumeAfterCatchExceptionon linux-x64 and osx-arm64, and fails a Checked consistency check on windows-x64.*(ULONG64*)targetSSP == pContext->RipinExecuteFunctionBelowContext.Note
This PR was prepared with AI assistance (Anthropic Claude, checked by OpenAI Codex) at my request. I reviewed it before posting it.