Skip to content
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

[mono][interp] Properly handle exceptions thrown by mono_marshal_get_native_wrapper #110232

Merged
merged 3 commits into from
Nov 29, 2024

Conversation

BrzVlad
Copy link
Member

@BrzVlad BrzVlad commented Nov 27, 2024

mono_marshal_get_native_wrapper can run some managed callbacks that can end up throwing an exception. This means both that if an exception is thrown we could leak compilation data and we weren't checking for the resume state, leading to executing bogus code when returning. This PR follows the approach JIT from mono/mono#20177 to defer the throwing of exception when the method is actually called and not during compilation and we add the necessary resume state checks.

Should fix #101370

…ution

This can end up calling into managed where exceptions can be thrown. Throwing exceptions while method compilation happens in not valid behavior. This follows the same approach from the jit side in mono/mono#20177.
We always optimize managed wrappers. If we are attempting to compile and execute a pinvoke method, we will use the m2n wrapper instead. Make sure we check for this when disabling tiering, since swift interop relies on these wrappers to be always optimized.
@@ -2692,8 +2692,6 @@ static MonoMethod*
interp_transform_internal_calls (MonoMethod *method, MonoMethod *target_method, MonoMethodSignature *csignature, gboolean is_virtual)
{
if (((method->wrapper_type == MONO_WRAPPER_NONE) || (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD)) && target_method != NULL) {
if (target_method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
target_method = mono_marshal_get_native_wrapper (target_method, FALSE, FALSE);
if (!is_virtual && target_method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
target_method = mono_marshal_get_synchronized_wrapper (target_method);
Copy link
Member

Choose a reason for hiding this comment

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

Can mono_marshal_get_synchronized_wrapper run managed callbacks that can end up throwing an exception as well?

Copy link
Member Author

Choose a reason for hiding this comment

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

No. This scenario was happening when looking up for the pinvoke call in libraries, which is not relevant for the synchronized wrapper.

@BrzVlad BrzVlad merged commit aba8199 into dotnet:main Nov 29, 2024
68 of 70 checks passed
eduardo-vp pushed a commit to eduardo-vp/runtime that referenced this pull request Dec 5, 2024
…native_wrapper (dotnet#110232)

* [mono][interp] Defer calls to mono_marshal_get_native_wrapper at execution

This can end up calling into managed where exceptions can be thrown. Throwing exceptions while method compilation happens in not valid behavior. This follows the same approach from the jit side in mono/mono#20177.

* [mono][interp] Check resume state when returning from method compilation

* [mono][interp] Fix tiering disable condition

We always optimize managed wrappers. If we are attempting to compile and execute a pinvoke method, we will use the m2n wrapper instead. Make sure we check for this when disabling tiering, since swift interop relies on these wrappers to be always optimized.
mikelle-rogers pushed a commit to mikelle-rogers/runtime that referenced this pull request Dec 10, 2024
…native_wrapper (dotnet#110232)

* [mono][interp] Defer calls to mono_marshal_get_native_wrapper at execution

This can end up calling into managed where exceptions can be thrown. Throwing exceptions while method compilation happens in not valid behavior. This follows the same approach from the jit side in mono/mono#20177.

* [mono][interp] Check resume state when returning from method compilation

* [mono][interp] Fix tiering disable condition

We always optimize managed wrappers. If we are attempting to compile and execute a pinvoke method, we will use the m2n wrapper instead. Make sure we check for this when disabling tiering, since swift interop relies on these wrappers to be always optimized.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants