Move coreclr EH second pass to native code - #119863

Merged
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native
Sep 29, 2025
Merged

Move coreclr EH second pass to native code#119863
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native

Conversation

@janvorli

Copy link
Copy Markdown
Member

There were some GC holes discovered caused by the fact that GC can be triggered during 2nd pass of EH in-between calls to finally handlers and catch handler. After considering options, moving the 2nd pass to native code seems the most reasonable solution.

There were some GC holes discovered caused by the fact that GC can be
triggered during 2nd pass of EH in-between calls to finally handlers and
catch handler. After considering options, moving the 2nd pass to native
code seems the most reasonable solution.
@janvorlijanvorli added this to the 10.0.0 milestone Sep 18, 2025
@janvorlijanvorli self-assigned this Sep 18, 2025
CopilotAI review requested due to automatic review settings September 18, 2025 20:04
@janvorlijanvorli added NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) area-ExceptionHandling-coreclr only use for closed issues labels Sep 18, 2025
@janvorli

Copy link
Copy Markdown
MemberAuthor

The current state is that it almost works. A catch handler is correctly invoked, but then something crashes.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 moves the CoreCLR exception handling second pass from managed to native code to fix GC holes that can occur when GC is triggered between finally handlers and catch handlers during the second pass of exception handling.

  • Splits existing RhThrowEx/RhThrowHwEx methods into separate first-pass handler finding methods and second-pass execution
  • Moves the second pass execution logic (DispatchExPass2) from managed to native code
  • Removes QCALL exports for CallCatchFunclet and CallFinallyFunclet as they're now called directly from native code

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/coreclr/vm/qcallentrypoints.cppRemoves QCALL exports for CallCatchFunclet and CallFinallyFunclet
src/coreclr/vm/metasig.hUpdates method signatures to include handlingFrameSP and pCatchHandler out parameters
src/coreclr/vm/exinfo.hAdds ContainsCodeOffset helper method to RhEHClause
src/coreclr/vm/exceptionhandlingqcalls.hRemoves QCALL declarations for catch/finally funclets
src/coreclr/vm/exceptionhandling.hAdds declaration for new native DispatchExPass2 function
src/coreclr/vm/exceptionhandling.cppMajor refactoring: converts QCALL functions to native, adds new DispatchExPass2 implementation
src/coreclr/vm/excep.cppUpdates managed fault handling to use new method signatures
src/coreclr/vm/corelib.hUpdates method name mappings for exception handling entry points
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.csSplits exception handling into separate first/second pass methods

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

Also, please note that the collided unwind detection is not working yet, as I cannot rely on the pinvokes from the managed EH code anymore. I am working on a fix.
With the contract and EH clauses enumeration fixes based on David's feedback, many EH tests now pass until I hit one with collided unwind. I am reusing the interpreter test ran without interpreter for now.

@janvorli

Copy link
Copy Markdown
MemberAuthor

And one more thing not done yet is rethrow.

* Reflect PR feedback
* Implement rethrow
* Implement new way of collided unwind detection now that the
CallCatchFunclet is not called via pinvoke
* Remove forced reporting of EH code from stack frame iterator, as we
now cannot have that code on the stack during 2nd pass
@jkotasjkotas added the arch-wasm WebAssembly architecture label Sep 19, 2025
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@janvorli

Copy link
Copy Markdown
MemberAuthor

I am considering reducing the number of changes in the exceptionhandling.cs by a slightly different approach - keeping only the methods we had and adding an extra argument "firstPassOnly" to them. Then if that argument is set to true, in DispatchEx store the handlingFrameSP/PC, _pReversePInvokePropagationCallback/Context and the pCatchHandler into the ExInfo and return;
The native side would then take these from the ExInfo. On NativeAOT, this argument would be ignored.

The current state is that, with some additional changes that I am going to commit after I fix the offsets in StackFrameIterator for some targets, it passes all diagnostics tests and coreclr tests (except ForeignThreadExceptionTest where it ends up messing GC mode when calling managed callback from native code catch)

I also need to add proper contracts here and there.

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr gcstress0x3-gcstress0xc

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

This is done to ensure that no GC is allowed between the scanned stack
range is extended and a funclet for the current frame is called.
@janvorli

Copy link
Copy Markdown
MemberAuthor

@jkotas, @davidwrighton the current state of this PR is final from my point of view. Can you please review it?

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe this is correct and will fix the gc issue. I wish this invariant could be better documented/tested.

@janvorli
janvorli merged commit bf4802d into dotnet:mainSep 29, 2025
98 checks passed
@janvorli

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0: https://github.com/dotnet/runtime/actions/runs/18106203717

@github-actions

Copy link
Copy Markdown
Contributor

@janvorli backporting to "release/10.0" failed, the patch most likely resulted in conflicts:

$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch
Applying: [WIP] Move coreclr EH second pass to native code
Applying: Several fixes
Applying: Fix arm64 build and remove now useless stuff from stackwalk
Applying: Fix build break
Applying: Fix offsets, exception interception and MUSL build break
Applying: Alternative change with minimalistic managed code differences
error: sha1 information is lacking or useless (src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0006 Alternative change with minimalistic managed code differences
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-ExceptionHandling-coreclronly use for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@janvorli@davidwrighton@kg@jkotas@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Move coreclr EH second pass to native code - #119863

Merged
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native
Sep 29, 2025
Merged

Move coreclr EH second pass to native code#119863
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native

Conversation

@janvorli

Copy link
Copy Markdown
Member

There were some GC holes discovered caused by the fact that GC can be triggered during 2nd pass of EH in-between calls to finally handlers and catch handler. After considering options, moving the 2nd pass to native code seems the most reasonable solution.

There were some GC holes discovered caused by the fact that GC can be
triggered during 2nd pass of EH in-between calls to finally handlers and
catch handler. After considering options, moving the 2nd pass to native
code seems the most reasonable solution.
@janvorlijanvorli added this to the 10.0.0 milestone Sep 18, 2025
@janvorlijanvorli self-assigned this Sep 18, 2025
CopilotAI review requested due to automatic review settings September 18, 2025 20:04
@janvorlijanvorli added NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) area-ExceptionHandling-coreclr only use for closed issues labels Sep 18, 2025
@janvorli

Copy link
Copy Markdown
MemberAuthor

The current state is that it almost works. A catch handler is correctly invoked, but then something crashes.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 moves the CoreCLR exception handling second pass from managed to native code to fix GC holes that can occur when GC is triggered between finally handlers and catch handlers during the second pass of exception handling.

  • Splits existing RhThrowEx/RhThrowHwEx methods into separate first-pass handler finding methods and second-pass execution
  • Moves the second pass execution logic (DispatchExPass2) from managed to native code
  • Removes QCALL exports for CallCatchFunclet and CallFinallyFunclet as they're now called directly from native code

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/coreclr/vm/qcallentrypoints.cppRemoves QCALL exports for CallCatchFunclet and CallFinallyFunclet
src/coreclr/vm/metasig.hUpdates method signatures to include handlingFrameSP and pCatchHandler out parameters
src/coreclr/vm/exinfo.hAdds ContainsCodeOffset helper method to RhEHClause
src/coreclr/vm/exceptionhandlingqcalls.hRemoves QCALL declarations for catch/finally funclets
src/coreclr/vm/exceptionhandling.hAdds declaration for new native DispatchExPass2 function
src/coreclr/vm/exceptionhandling.cppMajor refactoring: converts QCALL functions to native, adds new DispatchExPass2 implementation
src/coreclr/vm/excep.cppUpdates managed fault handling to use new method signatures
src/coreclr/vm/corelib.hUpdates method name mappings for exception handling entry points
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.csSplits exception handling into separate first/second pass methods

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

Also, please note that the collided unwind detection is not working yet, as I cannot rely on the pinvokes from the managed EH code anymore. I am working on a fix.
With the contract and EH clauses enumeration fixes based on David's feedback, many EH tests now pass until I hit one with collided unwind. I am reusing the interpreter test ran without interpreter for now.

@janvorli

Copy link
Copy Markdown
MemberAuthor

And one more thing not done yet is rethrow.

* Reflect PR feedback
* Implement rethrow
* Implement new way of collided unwind detection now that the
CallCatchFunclet is not called via pinvoke
* Remove forced reporting of EH code from stack frame iterator, as we
now cannot have that code on the stack during 2nd pass
@jkotasjkotas added the arch-wasm WebAssembly architecture label Sep 19, 2025
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@janvorli

Copy link
Copy Markdown
MemberAuthor

I am considering reducing the number of changes in the exceptionhandling.cs by a slightly different approach - keeping only the methods we had and adding an extra argument "firstPassOnly" to them. Then if that argument is set to true, in DispatchEx store the handlingFrameSP/PC, _pReversePInvokePropagationCallback/Context and the pCatchHandler into the ExInfo and return;
The native side would then take these from the ExInfo. On NativeAOT, this argument would be ignored.

The current state is that, with some additional changes that I am going to commit after I fix the offsets in StackFrameIterator for some targets, it passes all diagnostics tests and coreclr tests (except ForeignThreadExceptionTest where it ends up messing GC mode when calling managed callback from native code catch)

I also need to add proper contracts here and there.

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr gcstress0x3-gcstress0xc

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

This is done to ensure that no GC is allowed between the scanned stack
range is extended and a funclet for the current frame is called.
@janvorli

Copy link
Copy Markdown
MemberAuthor

@jkotas, @davidwrighton the current state of this PR is final from my point of view. Can you please review it?

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe this is correct and will fix the gc issue. I wish this invariant could be better documented/tested.

@janvorli
janvorli merged commit bf4802d into dotnet:mainSep 29, 2025
98 checks passed
@janvorli

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0: https://github.com/dotnet/runtime/actions/runs/18106203717

@github-actions

Copy link
Copy Markdown
Contributor

@janvorli backporting to "release/10.0" failed, the patch most likely resulted in conflicts:

$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch
Applying: [WIP] Move coreclr EH second pass to native code
Applying: Several fixes
Applying: Fix arm64 build and remove now useless stuff from stackwalk
Applying: Fix build break
Applying: Fix offsets, exception interception and MUSL build break
Applying: Alternative change with minimalistic managed code differences
error: sha1 information is lacking or useless (src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0006 Alternative change with minimalistic managed code differences
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-ExceptionHandling-coreclronly use for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@janvorli@davidwrighton@kg@jkotas@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Move coreclr EH second pass to native code - #119863

Merged
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native
Sep 29, 2025
Merged

Move coreclr EH second pass to native code#119863
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native

Conversation

@janvorli

Copy link
Copy Markdown
Member

There were some GC holes discovered caused by the fact that GC can be triggered during 2nd pass of EH in-between calls to finally handlers and catch handler. After considering options, moving the 2nd pass to native code seems the most reasonable solution.

There were some GC holes discovered caused by the fact that GC can be
triggered during 2nd pass of EH in-between calls to finally handlers and
catch handler. After considering options, moving the 2nd pass to native
code seems the most reasonable solution.
@janvorlijanvorli added this to the 10.0.0 milestone Sep 18, 2025
@janvorlijanvorli self-assigned this Sep 18, 2025
CopilotAI review requested due to automatic review settings September 18, 2025 20:04
@janvorlijanvorli added NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) area-ExceptionHandling-coreclr only use for closed issues labels Sep 18, 2025
@janvorli

Copy link
Copy Markdown
MemberAuthor

The current state is that it almost works. A catch handler is correctly invoked, but then something crashes.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 moves the CoreCLR exception handling second pass from managed to native code to fix GC holes that can occur when GC is triggered between finally handlers and catch handlers during the second pass of exception handling.

  • Splits existing RhThrowEx/RhThrowHwEx methods into separate first-pass handler finding methods and second-pass execution
  • Moves the second pass execution logic (DispatchExPass2) from managed to native code
  • Removes QCALL exports for CallCatchFunclet and CallFinallyFunclet as they're now called directly from native code

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/coreclr/vm/qcallentrypoints.cppRemoves QCALL exports for CallCatchFunclet and CallFinallyFunclet
src/coreclr/vm/metasig.hUpdates method signatures to include handlingFrameSP and pCatchHandler out parameters
src/coreclr/vm/exinfo.hAdds ContainsCodeOffset helper method to RhEHClause
src/coreclr/vm/exceptionhandlingqcalls.hRemoves QCALL declarations for catch/finally funclets
src/coreclr/vm/exceptionhandling.hAdds declaration for new native DispatchExPass2 function
src/coreclr/vm/exceptionhandling.cppMajor refactoring: converts QCALL functions to native, adds new DispatchExPass2 implementation
src/coreclr/vm/excep.cppUpdates managed fault handling to use new method signatures
src/coreclr/vm/corelib.hUpdates method name mappings for exception handling entry points
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.csSplits exception handling into separate first/second pass methods

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

Also, please note that the collided unwind detection is not working yet, as I cannot rely on the pinvokes from the managed EH code anymore. I am working on a fix.
With the contract and EH clauses enumeration fixes based on David's feedback, many EH tests now pass until I hit one with collided unwind. I am reusing the interpreter test ran without interpreter for now.

@janvorli

Copy link
Copy Markdown
MemberAuthor

And one more thing not done yet is rethrow.

* Reflect PR feedback
* Implement rethrow
* Implement new way of collided unwind detection now that the
CallCatchFunclet is not called via pinvoke
* Remove forced reporting of EH code from stack frame iterator, as we
now cannot have that code on the stack during 2nd pass
@jkotasjkotas added the arch-wasm WebAssembly architecture label Sep 19, 2025
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@janvorli

Copy link
Copy Markdown
MemberAuthor

I am considering reducing the number of changes in the exceptionhandling.cs by a slightly different approach - keeping only the methods we had and adding an extra argument "firstPassOnly" to them. Then if that argument is set to true, in DispatchEx store the handlingFrameSP/PC, _pReversePInvokePropagationCallback/Context and the pCatchHandler into the ExInfo and return;
The native side would then take these from the ExInfo. On NativeAOT, this argument would be ignored.

The current state is that, with some additional changes that I am going to commit after I fix the offsets in StackFrameIterator for some targets, it passes all diagnostics tests and coreclr tests (except ForeignThreadExceptionTest where it ends up messing GC mode when calling managed callback from native code catch)

I also need to add proper contracts here and there.

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr gcstress0x3-gcstress0xc

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

This is done to ensure that no GC is allowed between the scanned stack
range is extended and a funclet for the current frame is called.
@janvorli

Copy link
Copy Markdown
MemberAuthor

@jkotas, @davidwrighton the current state of this PR is final from my point of view. Can you please review it?

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe this is correct and will fix the gc issue. I wish this invariant could be better documented/tested.

@janvorli
janvorli merged commit bf4802d into dotnet:mainSep 29, 2025
98 checks passed
@janvorli

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0: https://github.com/dotnet/runtime/actions/runs/18106203717

@github-actions

Copy link
Copy Markdown
Contributor

@janvorli backporting to "release/10.0" failed, the patch most likely resulted in conflicts:

$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch
Applying: [WIP] Move coreclr EH second pass to native code
Applying: Several fixes
Applying: Fix arm64 build and remove now useless stuff from stackwalk
Applying: Fix build break
Applying: Fix offsets, exception interception and MUSL build break
Applying: Alternative change with minimalistic managed code differences
error: sha1 information is lacking or useless (src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0006 Alternative change with minimalistic managed code differences
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-ExceptionHandling-coreclronly use for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@janvorli@davidwrighton@kg@jkotas@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Move coreclr EH second pass to native code - #119863

Merged
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native
Sep 29, 2025
Merged

Move coreclr EH second pass to native code#119863
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native

Conversation

@janvorli

Copy link
Copy Markdown
Member

There were some GC holes discovered caused by the fact that GC can be triggered during 2nd pass of EH in-between calls to finally handlers and catch handler. After considering options, moving the 2nd pass to native code seems the most reasonable solution.

There were some GC holes discovered caused by the fact that GC can be
triggered during 2nd pass of EH in-between calls to finally handlers and
catch handler. After considering options, moving the 2nd pass to native
code seems the most reasonable solution.
@janvorlijanvorli added this to the 10.0.0 milestone Sep 18, 2025
@janvorlijanvorli self-assigned this Sep 18, 2025
CopilotAI review requested due to automatic review settings September 18, 2025 20:04
@janvorlijanvorli added NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) area-ExceptionHandling-coreclr only use for closed issues labels Sep 18, 2025
@janvorli

Copy link
Copy Markdown
MemberAuthor

The current state is that it almost works. A catch handler is correctly invoked, but then something crashes.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 moves the CoreCLR exception handling second pass from managed to native code to fix GC holes that can occur when GC is triggered between finally handlers and catch handlers during the second pass of exception handling.

  • Splits existing RhThrowEx/RhThrowHwEx methods into separate first-pass handler finding methods and second-pass execution
  • Moves the second pass execution logic (DispatchExPass2) from managed to native code
  • Removes QCALL exports for CallCatchFunclet and CallFinallyFunclet as they're now called directly from native code

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/coreclr/vm/qcallentrypoints.cppRemoves QCALL exports for CallCatchFunclet and CallFinallyFunclet
src/coreclr/vm/metasig.hUpdates method signatures to include handlingFrameSP and pCatchHandler out parameters
src/coreclr/vm/exinfo.hAdds ContainsCodeOffset helper method to RhEHClause
src/coreclr/vm/exceptionhandlingqcalls.hRemoves QCALL declarations for catch/finally funclets
src/coreclr/vm/exceptionhandling.hAdds declaration for new native DispatchExPass2 function
src/coreclr/vm/exceptionhandling.cppMajor refactoring: converts QCALL functions to native, adds new DispatchExPass2 implementation
src/coreclr/vm/excep.cppUpdates managed fault handling to use new method signatures
src/coreclr/vm/corelib.hUpdates method name mappings for exception handling entry points
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.csSplits exception handling into separate first/second pass methods

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

Also, please note that the collided unwind detection is not working yet, as I cannot rely on the pinvokes from the managed EH code anymore. I am working on a fix.
With the contract and EH clauses enumeration fixes based on David's feedback, many EH tests now pass until I hit one with collided unwind. I am reusing the interpreter test ran without interpreter for now.

@janvorli

Copy link
Copy Markdown
MemberAuthor

And one more thing not done yet is rethrow.

* Reflect PR feedback
* Implement rethrow
* Implement new way of collided unwind detection now that the
CallCatchFunclet is not called via pinvoke
* Remove forced reporting of EH code from stack frame iterator, as we
now cannot have that code on the stack during 2nd pass
@jkotasjkotas added the arch-wasm WebAssembly architecture label Sep 19, 2025
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@janvorli

Copy link
Copy Markdown
MemberAuthor

I am considering reducing the number of changes in the exceptionhandling.cs by a slightly different approach - keeping only the methods we had and adding an extra argument "firstPassOnly" to them. Then if that argument is set to true, in DispatchEx store the handlingFrameSP/PC, _pReversePInvokePropagationCallback/Context and the pCatchHandler into the ExInfo and return;
The native side would then take these from the ExInfo. On NativeAOT, this argument would be ignored.

The current state is that, with some additional changes that I am going to commit after I fix the offsets in StackFrameIterator for some targets, it passes all diagnostics tests and coreclr tests (except ForeignThreadExceptionTest where it ends up messing GC mode when calling managed callback from native code catch)

I also need to add proper contracts here and there.

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr gcstress0x3-gcstress0xc

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

This is done to ensure that no GC is allowed between the scanned stack
range is extended and a funclet for the current frame is called.
@janvorli

Copy link
Copy Markdown
MemberAuthor

@jkotas, @davidwrighton the current state of this PR is final from my point of view. Can you please review it?

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe this is correct and will fix the gc issue. I wish this invariant could be better documented/tested.

@janvorli
janvorli merged commit bf4802d into dotnet:mainSep 29, 2025
98 checks passed
@janvorli

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0: https://github.com/dotnet/runtime/actions/runs/18106203717

@github-actions

Copy link
Copy Markdown
Contributor

@janvorli backporting to "release/10.0" failed, the patch most likely resulted in conflicts:

$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch
Applying: [WIP] Move coreclr EH second pass to native code
Applying: Several fixes
Applying: Fix arm64 build and remove now useless stuff from stackwalk
Applying: Fix build break
Applying: Fix offsets, exception interception and MUSL build break
Applying: Alternative change with minimalistic managed code differences
error: sha1 information is lacking or useless (src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0006 Alternative change with minimalistic managed code differences
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-ExceptionHandling-coreclronly use for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@janvorli@davidwrighton@kg@jkotas@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Move coreclr EH second pass to native code - #119863

Merged
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native
Sep 29, 2025
Merged

Move coreclr EH second pass to native code#119863
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native

Conversation

@janvorli

Copy link
Copy Markdown
Member

There were some GC holes discovered caused by the fact that GC can be triggered during 2nd pass of EH in-between calls to finally handlers and catch handler. After considering options, moving the 2nd pass to native code seems the most reasonable solution.

There were some GC holes discovered caused by the fact that GC can be
triggered during 2nd pass of EH in-between calls to finally handlers and
catch handler. After considering options, moving the 2nd pass to native
code seems the most reasonable solution.
@janvorlijanvorli added this to the 10.0.0 milestone Sep 18, 2025
@janvorlijanvorli self-assigned this Sep 18, 2025
CopilotAI review requested due to automatic review settings September 18, 2025 20:04
@janvorlijanvorli added NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) area-ExceptionHandling-coreclr only use for closed issues labels Sep 18, 2025
@janvorli

Copy link
Copy Markdown
MemberAuthor

The current state is that it almost works. A catch handler is correctly invoked, but then something crashes.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 moves the CoreCLR exception handling second pass from managed to native code to fix GC holes that can occur when GC is triggered between finally handlers and catch handlers during the second pass of exception handling.

  • Splits existing RhThrowEx/RhThrowHwEx methods into separate first-pass handler finding methods and second-pass execution
  • Moves the second pass execution logic (DispatchExPass2) from managed to native code
  • Removes QCALL exports for CallCatchFunclet and CallFinallyFunclet as they're now called directly from native code

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/coreclr/vm/qcallentrypoints.cppRemoves QCALL exports for CallCatchFunclet and CallFinallyFunclet
src/coreclr/vm/metasig.hUpdates method signatures to include handlingFrameSP and pCatchHandler out parameters
src/coreclr/vm/exinfo.hAdds ContainsCodeOffset helper method to RhEHClause
src/coreclr/vm/exceptionhandlingqcalls.hRemoves QCALL declarations for catch/finally funclets
src/coreclr/vm/exceptionhandling.hAdds declaration for new native DispatchExPass2 function
src/coreclr/vm/exceptionhandling.cppMajor refactoring: converts QCALL functions to native, adds new DispatchExPass2 implementation
src/coreclr/vm/excep.cppUpdates managed fault handling to use new method signatures
src/coreclr/vm/corelib.hUpdates method name mappings for exception handling entry points
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.csSplits exception handling into separate first/second pass methods

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

Also, please note that the collided unwind detection is not working yet, as I cannot rely on the pinvokes from the managed EH code anymore. I am working on a fix.
With the contract and EH clauses enumeration fixes based on David's feedback, many EH tests now pass until I hit one with collided unwind. I am reusing the interpreter test ran without interpreter for now.

@janvorli

Copy link
Copy Markdown
MemberAuthor

And one more thing not done yet is rethrow.

* Reflect PR feedback
* Implement rethrow
* Implement new way of collided unwind detection now that the
CallCatchFunclet is not called via pinvoke
* Remove forced reporting of EH code from stack frame iterator, as we
now cannot have that code on the stack during 2nd pass
@jkotasjkotas added the arch-wasm WebAssembly architecture label Sep 19, 2025
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@janvorli

Copy link
Copy Markdown
MemberAuthor

I am considering reducing the number of changes in the exceptionhandling.cs by a slightly different approach - keeping only the methods we had and adding an extra argument "firstPassOnly" to them. Then if that argument is set to true, in DispatchEx store the handlingFrameSP/PC, _pReversePInvokePropagationCallback/Context and the pCatchHandler into the ExInfo and return;
The native side would then take these from the ExInfo. On NativeAOT, this argument would be ignored.

The current state is that, with some additional changes that I am going to commit after I fix the offsets in StackFrameIterator for some targets, it passes all diagnostics tests and coreclr tests (except ForeignThreadExceptionTest where it ends up messing GC mode when calling managed callback from native code catch)

I also need to add proper contracts here and there.

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr gcstress0x3-gcstress0xc

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

This is done to ensure that no GC is allowed between the scanned stack
range is extended and a funclet for the current frame is called.
@janvorli

Copy link
Copy Markdown
MemberAuthor

@jkotas, @davidwrighton the current state of this PR is final from my point of view. Can you please review it?

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe this is correct and will fix the gc issue. I wish this invariant could be better documented/tested.

@janvorli
janvorli merged commit bf4802d into dotnet:mainSep 29, 2025
98 checks passed
@janvorli

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0: https://github.com/dotnet/runtime/actions/runs/18106203717

@github-actions

Copy link
Copy Markdown
Contributor

@janvorli backporting to "release/10.0" failed, the patch most likely resulted in conflicts:

$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch
Applying: [WIP] Move coreclr EH second pass to native code
Applying: Several fixes
Applying: Fix arm64 build and remove now useless stuff from stackwalk
Applying: Fix build break
Applying: Fix offsets, exception interception and MUSL build break
Applying: Alternative change with minimalistic managed code differences
error: sha1 information is lacking or useless (src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0006 Alternative change with minimalistic managed code differences
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-ExceptionHandling-coreclronly use for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@janvorli@davidwrighton@kg@jkotas@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Move coreclr EH second pass to native code - #119863

Merged
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native
Sep 29, 2025
Merged

Move coreclr EH second pass to native code#119863
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native

Conversation

@janvorli

Copy link
Copy Markdown
Member

There were some GC holes discovered caused by the fact that GC can be triggered during 2nd pass of EH in-between calls to finally handlers and catch handler. After considering options, moving the 2nd pass to native code seems the most reasonable solution.

There were some GC holes discovered caused by the fact that GC can be
triggered during 2nd pass of EH in-between calls to finally handlers and
catch handler. After considering options, moving the 2nd pass to native
code seems the most reasonable solution.
@janvorlijanvorli added this to the 10.0.0 milestone Sep 18, 2025
@janvorlijanvorli self-assigned this Sep 18, 2025
CopilotAI review requested due to automatic review settings September 18, 2025 20:04
@janvorlijanvorli added NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) area-ExceptionHandling-coreclr only use for closed issues labels Sep 18, 2025
@janvorli

Copy link
Copy Markdown
MemberAuthor

The current state is that it almost works. A catch handler is correctly invoked, but then something crashes.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 moves the CoreCLR exception handling second pass from managed to native code to fix GC holes that can occur when GC is triggered between finally handlers and catch handlers during the second pass of exception handling.

  • Splits existing RhThrowEx/RhThrowHwEx methods into separate first-pass handler finding methods and second-pass execution
  • Moves the second pass execution logic (DispatchExPass2) from managed to native code
  • Removes QCALL exports for CallCatchFunclet and CallFinallyFunclet as they're now called directly from native code

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/coreclr/vm/qcallentrypoints.cppRemoves QCALL exports for CallCatchFunclet and CallFinallyFunclet
src/coreclr/vm/metasig.hUpdates method signatures to include handlingFrameSP and pCatchHandler out parameters
src/coreclr/vm/exinfo.hAdds ContainsCodeOffset helper method to RhEHClause
src/coreclr/vm/exceptionhandlingqcalls.hRemoves QCALL declarations for catch/finally funclets
src/coreclr/vm/exceptionhandling.hAdds declaration for new native DispatchExPass2 function
src/coreclr/vm/exceptionhandling.cppMajor refactoring: converts QCALL functions to native, adds new DispatchExPass2 implementation
src/coreclr/vm/excep.cppUpdates managed fault handling to use new method signatures
src/coreclr/vm/corelib.hUpdates method name mappings for exception handling entry points
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.csSplits exception handling into separate first/second pass methods

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

Also, please note that the collided unwind detection is not working yet, as I cannot rely on the pinvokes from the managed EH code anymore. I am working on a fix.
With the contract and EH clauses enumeration fixes based on David's feedback, many EH tests now pass until I hit one with collided unwind. I am reusing the interpreter test ran without interpreter for now.

@janvorli

Copy link
Copy Markdown
MemberAuthor

And one more thing not done yet is rethrow.

* Reflect PR feedback
* Implement rethrow
* Implement new way of collided unwind detection now that the
CallCatchFunclet is not called via pinvoke
* Remove forced reporting of EH code from stack frame iterator, as we
now cannot have that code on the stack during 2nd pass
@jkotasjkotas added the arch-wasm WebAssembly architecture label Sep 19, 2025
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@janvorli

Copy link
Copy Markdown
MemberAuthor

I am considering reducing the number of changes in the exceptionhandling.cs by a slightly different approach - keeping only the methods we had and adding an extra argument "firstPassOnly" to them. Then if that argument is set to true, in DispatchEx store the handlingFrameSP/PC, _pReversePInvokePropagationCallback/Context and the pCatchHandler into the ExInfo and return;
The native side would then take these from the ExInfo. On NativeAOT, this argument would be ignored.

The current state is that, with some additional changes that I am going to commit after I fix the offsets in StackFrameIterator for some targets, it passes all diagnostics tests and coreclr tests (except ForeignThreadExceptionTest where it ends up messing GC mode when calling managed callback from native code catch)

I also need to add proper contracts here and there.

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr gcstress0x3-gcstress0xc

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

This is done to ensure that no GC is allowed between the scanned stack
range is extended and a funclet for the current frame is called.
@janvorli

Copy link
Copy Markdown
MemberAuthor

@jkotas, @davidwrighton the current state of this PR is final from my point of view. Can you please review it?

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe this is correct and will fix the gc issue. I wish this invariant could be better documented/tested.

@janvorli
janvorli merged commit bf4802d into dotnet:mainSep 29, 2025
98 checks passed
@janvorli

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0: https://github.com/dotnet/runtime/actions/runs/18106203717

@github-actions

Copy link
Copy Markdown
Contributor

@janvorli backporting to "release/10.0" failed, the patch most likely resulted in conflicts:

$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch
Applying: [WIP] Move coreclr EH second pass to native code
Applying: Several fixes
Applying: Fix arm64 build and remove now useless stuff from stackwalk
Applying: Fix build break
Applying: Fix offsets, exception interception and MUSL build break
Applying: Alternative change with minimalistic managed code differences
error: sha1 information is lacking or useless (src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0006 Alternative change with minimalistic managed code differences
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-ExceptionHandling-coreclronly use for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@janvorli@davidwrighton@kg@jkotas@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Move coreclr EH second pass to native code - #119863

Merged
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native
Sep 29, 2025
Merged

Move coreclr EH second pass to native code#119863
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native

Conversation

@janvorli

Copy link
Copy Markdown
Member

There were some GC holes discovered caused by the fact that GC can be triggered during 2nd pass of EH in-between calls to finally handlers and catch handler. After considering options, moving the 2nd pass to native code seems the most reasonable solution.

There were some GC holes discovered caused by the fact that GC can be
triggered during 2nd pass of EH in-between calls to finally handlers and
catch handler. After considering options, moving the 2nd pass to native
code seems the most reasonable solution.
@janvorlijanvorli added this to the 10.0.0 milestone Sep 18, 2025
@janvorlijanvorli self-assigned this Sep 18, 2025
CopilotAI review requested due to automatic review settings September 18, 2025 20:04
@janvorlijanvorli added NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) area-ExceptionHandling-coreclr only use for closed issues labels Sep 18, 2025
@janvorli

Copy link
Copy Markdown
MemberAuthor

The current state is that it almost works. A catch handler is correctly invoked, but then something crashes.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 moves the CoreCLR exception handling second pass from managed to native code to fix GC holes that can occur when GC is triggered between finally handlers and catch handlers during the second pass of exception handling.

  • Splits existing RhThrowEx/RhThrowHwEx methods into separate first-pass handler finding methods and second-pass execution
  • Moves the second pass execution logic (DispatchExPass2) from managed to native code
  • Removes QCALL exports for CallCatchFunclet and CallFinallyFunclet as they're now called directly from native code

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/coreclr/vm/qcallentrypoints.cppRemoves QCALL exports for CallCatchFunclet and CallFinallyFunclet
src/coreclr/vm/metasig.hUpdates method signatures to include handlingFrameSP and pCatchHandler out parameters
src/coreclr/vm/exinfo.hAdds ContainsCodeOffset helper method to RhEHClause
src/coreclr/vm/exceptionhandlingqcalls.hRemoves QCALL declarations for catch/finally funclets
src/coreclr/vm/exceptionhandling.hAdds declaration for new native DispatchExPass2 function
src/coreclr/vm/exceptionhandling.cppMajor refactoring: converts QCALL functions to native, adds new DispatchExPass2 implementation
src/coreclr/vm/excep.cppUpdates managed fault handling to use new method signatures
src/coreclr/vm/corelib.hUpdates method name mappings for exception handling entry points
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.csSplits exception handling into separate first/second pass methods

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

Also, please note that the collided unwind detection is not working yet, as I cannot rely on the pinvokes from the managed EH code anymore. I am working on a fix.
With the contract and EH clauses enumeration fixes based on David's feedback, many EH tests now pass until I hit one with collided unwind. I am reusing the interpreter test ran without interpreter for now.

@janvorli

Copy link
Copy Markdown
MemberAuthor

And one more thing not done yet is rethrow.

* Reflect PR feedback
* Implement rethrow
* Implement new way of collided unwind detection now that the
CallCatchFunclet is not called via pinvoke
* Remove forced reporting of EH code from stack frame iterator, as we
now cannot have that code on the stack during 2nd pass
@jkotasjkotas added the arch-wasm WebAssembly architecture label Sep 19, 2025
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@janvorli

Copy link
Copy Markdown
MemberAuthor

I am considering reducing the number of changes in the exceptionhandling.cs by a slightly different approach - keeping only the methods we had and adding an extra argument "firstPassOnly" to them. Then if that argument is set to true, in DispatchEx store the handlingFrameSP/PC, _pReversePInvokePropagationCallback/Context and the pCatchHandler into the ExInfo and return;
The native side would then take these from the ExInfo. On NativeAOT, this argument would be ignored.

The current state is that, with some additional changes that I am going to commit after I fix the offsets in StackFrameIterator for some targets, it passes all diagnostics tests and coreclr tests (except ForeignThreadExceptionTest where it ends up messing GC mode when calling managed callback from native code catch)

I also need to add proper contracts here and there.

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr gcstress0x3-gcstress0xc

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

This is done to ensure that no GC is allowed between the scanned stack
range is extended and a funclet for the current frame is called.
@janvorli

Copy link
Copy Markdown
MemberAuthor

@jkotas, @davidwrighton the current state of this PR is final from my point of view. Can you please review it?

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe this is correct and will fix the gc issue. I wish this invariant could be better documented/tested.

@janvorli
janvorli merged commit bf4802d into dotnet:mainSep 29, 2025
98 checks passed
@janvorli

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0: https://github.com/dotnet/runtime/actions/runs/18106203717

@github-actions

Copy link
Copy Markdown
Contributor

@janvorli backporting to "release/10.0" failed, the patch most likely resulted in conflicts:

$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch
Applying: [WIP] Move coreclr EH second pass to native code
Applying: Several fixes
Applying: Fix arm64 build and remove now useless stuff from stackwalk
Applying: Fix build break
Applying: Fix offsets, exception interception and MUSL build break
Applying: Alternative change with minimalistic managed code differences
error: sha1 information is lacking or useless (src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0006 Alternative change with minimalistic managed code differences
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-ExceptionHandling-coreclronly use for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@janvorli@davidwrighton@kg@jkotas@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Move coreclr EH second pass to native code - #119863

Merged
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native
Sep 29, 2025
Merged

Move coreclr EH second pass to native code#119863
janvorli merged 15 commits into
dotnet:mainfrom
janvorli:move-eh-2nd-pass-to-native

Conversation

@janvorli

Copy link
Copy Markdown
Member

There were some GC holes discovered caused by the fact that GC can be triggered during 2nd pass of EH in-between calls to finally handlers and catch handler. After considering options, moving the 2nd pass to native code seems the most reasonable solution.

There were some GC holes discovered caused by the fact that GC can be
triggered during 2nd pass of EH in-between calls to finally handlers and
catch handler. After considering options, moving the 2nd pass to native
code seems the most reasonable solution.
@janvorlijanvorli added this to the 10.0.0 milestone Sep 18, 2025
@janvorlijanvorli self-assigned this Sep 18, 2025
CopilotAI review requested due to automatic review settings September 18, 2025 20:04
@janvorlijanvorli added NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) area-ExceptionHandling-coreclr only use for closed issues labels Sep 18, 2025
@janvorli

Copy link
Copy Markdown
MemberAuthor

The current state is that it almost works. A catch handler is correctly invoked, but then something crashes.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 moves the CoreCLR exception handling second pass from managed to native code to fix GC holes that can occur when GC is triggered between finally handlers and catch handlers during the second pass of exception handling.

  • Splits existing RhThrowEx/RhThrowHwEx methods into separate first-pass handler finding methods and second-pass execution
  • Moves the second pass execution logic (DispatchExPass2) from managed to native code
  • Removes QCALL exports for CallCatchFunclet and CallFinallyFunclet as they're now called directly from native code

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
src/coreclr/vm/qcallentrypoints.cppRemoves QCALL exports for CallCatchFunclet and CallFinallyFunclet
src/coreclr/vm/metasig.hUpdates method signatures to include handlingFrameSP and pCatchHandler out parameters
src/coreclr/vm/exinfo.hAdds ContainsCodeOffset helper method to RhEHClause
src/coreclr/vm/exceptionhandlingqcalls.hRemoves QCALL declarations for catch/finally funclets
src/coreclr/vm/exceptionhandling.hAdds declaration for new native DispatchExPass2 function
src/coreclr/vm/exceptionhandling.cppMajor refactoring: converts QCALL functions to native, adds new DispatchExPass2 implementation
src/coreclr/vm/excep.cppUpdates managed fault handling to use new method signatures
src/coreclr/vm/corelib.hUpdates method name mappings for exception handling entry points
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.csSplits exception handling into separate first/second pass methods

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

Also, please note that the collided unwind detection is not working yet, as I cannot rely on the pinvokes from the managed EH code anymore. I am working on a fix.
With the contract and EH clauses enumeration fixes based on David's feedback, many EH tests now pass until I hit one with collided unwind. I am reusing the interpreter test ran without interpreter for now.

@janvorli

Copy link
Copy Markdown
MemberAuthor

And one more thing not done yet is rethrow.

* Reflect PR feedback
* Implement rethrow
* Implement new way of collided unwind detection now that the
CallCatchFunclet is not called via pinvoke
* Remove forced reporting of EH code from stack frame iterator, as we
now cannot have that code on the stack during 2nd pass
@jkotasjkotas added the arch-wasm WebAssembly architecture label Sep 19, 2025
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@janvorli

Copy link
Copy Markdown
MemberAuthor

I am considering reducing the number of changes in the exceptionhandling.cs by a slightly different approach - keeping only the methods we had and adding an extra argument "firstPassOnly" to them. Then if that argument is set to true, in DispatchEx store the handlingFrameSP/PC, _pReversePInvokePropagationCallback/Context and the pCatchHandler into the ExInfo and return;
The native side would then take these from the ExInfo. On NativeAOT, this argument would be ignored.

The current state is that, with some additional changes that I am going to commit after I fix the offsets in StackFrameIterator for some targets, it passes all diagnostics tests and coreclr tests (except ForeignThreadExceptionTest where it ends up messing GC mode when calling managed callback from native code catch)

I also need to add proper contracts here and there.

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@janvorli

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr gcstress0x3-gcstress0xc

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

This is done to ensure that no GC is allowed between the scanned stack
range is extended and a funclet for the current frame is called.
@janvorli

Copy link
Copy Markdown
MemberAuthor

@jkotas, @davidwrighton the current state of this PR is final from my point of view. Can you please review it?

Comment threadsrc/coreclr/vm/exceptionhandling.cpp Outdated
Comment threadsrc/coreclr/vm/exceptionhandling.cpp

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe this is correct and will fix the gc issue. I wish this invariant could be better documented/tested.

@janvorli
janvorli merged commit bf4802d into dotnet:mainSep 29, 2025
98 checks passed
@janvorli

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0: https://github.com/dotnet/runtime/actions/runs/18106203717

@github-actions

Copy link
Copy Markdown
Contributor

@janvorli backporting to "release/10.0" failed, the patch most likely resulted in conflicts:

$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch
Applying: [WIP] Move coreclr EH second pass to native code
Applying: Several fixes
Applying: Fix arm64 build and remove now useless stuff from stackwalk
Applying: Fix build break
Applying: Fix offsets, exception interception and MUSL build break
Applying: Alternative change with minimalistic managed code differences
error: sha1 information is lacking or useless (src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0006 Alternative change with minimalistic managed code differences
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-ExceptionHandling-coreclronly use for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@janvorli@davidwrighton@kg@jkotas@SingleAccretion