Skip to content

[Mono]: Make sure interpreter gc_transitions gets reset on managed exceptions. #115052

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

lateralusX
Copy link
Member

Interpreters do_icall_wrapper and ves_pinvoke_method uses a frame variable called gc_transitions that can put thread in GC SAFE mode before calling native code and switch back on return. When interpreter calls native code it also push a LMF frame with context and unwind label so in case of managed exception it will continue execution at label, but in that case it would also miss to reset the gc_transitions flag. That could then lead to future errors since other icalls would run under incorrect GC state due to incorrect GC switch.

This issue was observed in #114840. In that case a custom icall could call mono_raise_exception that would hit this scenario, leaving the gc_transitions set to TRUE that would then cause issues since next icall would run in wrong GC mode causing undefined behavior.

Fix adds a mechanism to abort a GC safe region making sure thread gets back to GC unsafe mode and also make sure the cookie stack gets rebalanced on checked builds. It also makes sure gc_transitions gets reset to FALSE, if its still TRUE reaching the exit label.

Fix makes sure we correctly restore the interpreter GC state in case of a managed exception in native code.

…ced.

Interpreters do_icall_wrapper and ves_pinvoke_method uses a frame
variable called gc_transitions that can put thread in GC SAFE mode
before calling native code and switch back on return. When interpreter
calls native code it also push a LMF frame with context and unwind
label so in case of managed exception it will continue execution at
label, but in that case it would also miss to reset the gc_transitions
flag. That could then lead to future errors since other icalls would
run under incorrect GC state due to incorrect GC switch.

This issue was observed in dotnet#114840.
In that case a custom icall could call mono_raise_exception that would
hit this scenario, leaving the gc_transitions set to TRUE that would then
cause issues since next icall would run in wrong GC mode causing
undefined behaviour.

Fix adds a mechanism to abort a GC safe region making sure thread gets
back to GC unsafe mode and also make sure the cookie stack gets
rebalanced on checked builds. It also makes sure gc_transitions gets
reset to FALSE, if its still TRUE reaching the exit label.

Fix makes sure we correctly restore the interpreter GC state in case of a
managed exception in native code.
Copy link
Contributor

@Copilot Copilot AI left a 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 an imbalance in the GC safe/unsafe transitions when a managed exception occurs during interpreter calls. The changes add a new function to abort a GC safe region and adjust the behavior of both the p/invoke and icall wrappers.

  • Introduces mono_threads_abort_gc_safe_region_internal to rebalance the GC state.
  • Modifies ves_pinvoke_method and do_icall_wrapper to use stack‐data based GC safe region entry/exit and handle managed exceptions.
  • Updates header and implementation files accordingly.

Reviewed Changes

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

File Description
src/mono/mono/utils/mono-threads-coop.h Added declaration for aborting GC safe regions.
src/mono/mono/utils/mono-threads-coop.c Introduced mono_threads_abort_gc_safe_region_internal to rebalance GC state.
src/mono/mono/mini/interp/interp.c Updated wrappers to ensure balanced GC transitions on managed exceptions.

@lateralusX lateralusX changed the title [Mono]: Make sure interpreter gc_transitions on managed exceptions gets balanced. [Mono]: Make sure interpreter gc_transitions gets reset on managed exceptions. Apr 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants