From 91121498e08f2b0970052ca38be207445a3c1440 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Mon, 1 Jun 2020 17:29:03 -0400 Subject: [PATCH] [interp] Switch to GC Unsafe mode before calling get_interp_to_native_trampoline (#37135) * [interp] Switch to GC Unsafe mode before calling get_interp_to_native_trampoline For PInvokes, `ves_pinvoke_method` is called when we're interpreting the pinvoke wrapper, after it already executed a transition from GC Unsafe to GC Safe mode. At that point, calling back into the runtime we have to temporarily switch back to GC Unsafe mode. Example stack trace where we don't: ``` 0x10dbdd7d6 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : mono_dump_native_crash_info 0x10db7f665 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : mono_handle_native_crash 0x10dbdcf3f - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : sigabrt_signal_handler 0x7fff6886af5a - /usr/lib/system/libsystem_platform.dylib : _sigtramp 0x0 - Unknown 0x7fff686081ae - /usr/lib/system/libsystem_c.dylib : abort 0x10dd9e887 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : monoeg_assert_abort 0x10dd75257 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : mono_log_write_logfile 0x10dd9ed15 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : monoeg_g_logv_nofree 0x10dd9edd2 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : monoeg_g_log 0x10dd8b4fc - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : mono_threads_transition_do_blocking 0x10dd8cc63 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : mono_threads_enter_gc_safe_region_unbalanced_with_info 0x10dc40a39 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : mono_coop_mutex_lock 0x10dc41e05 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : mono_domain_alloc0 0x10dadba6f - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : mono_tramp_info_register_internal 0x10dbece91 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : get_interp_to_native_trampoline 0x10dbebaf9 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : ves_pinvoke_method 0x10dbe0e58 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : interp_exec_method 0x10dbdf17b - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : interp_runtime_invoke 0x10dcbae58 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : mono_runtime_invoke_checked 0x10dcbacf3 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : mono_runtime_object_init_handle 0x10dc6367f - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : mono_exception_new_by_name_domain 0x10dc63523 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : mono_exception_from_name_domain 0x10dbe81c6 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : interp_exec_method 0x10dbdf17b - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : interp_runtime_invoke 0x10dcbae58 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : mono_runtime_invoke_checked 0x10dcd6e69 - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : start_wrapper_internal 0x10dcd6b9e - /private/tmp/helix/working/B38709D8/p/libcoreclr.dylib : start_wrapper 0x7fff68874661 - /usr/lib/system/libsystem_pthread.dylib : _pthread_body 0x7fff6887450d - /usr/lib/system/libsystem_pthread.dylib : _pthread_body 0x7fff68873bf9 - /usr/lib/system/libsystem_pthread.dylib : thread_start ``` --- src/mono/mono/mini/interp/interp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 15656c8..541544f 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -1525,8 +1525,18 @@ ves_pinvoke_method ( g_assert (!frame.imethod); + /* + * When there's a calli in a pinvoke wrapper, we're in GC Safe mode. + * When we're called for some other calli, we may be in GC Unsafe mode. + * + * On any code path where we call anything other than the entry_func, + * we need to switch back to GC Unsafe before calling the runtime. + */ + MONO_REQ_GC_NEUTRAL_MODE; + static MonoPIFunc entry_func = NULL; if (!entry_func) { + MONO_ENTER_GC_UNSAFE; #ifdef MONO_ARCH_HAS_NO_PROPER_MONOCTX ERROR_DECL (error); entry_func = (MonoPIFunc) mono_jit_compile_method_jit_only (mini_get_interp_lmf_wrapper ("mono_interp_to_native_trampoline", (gpointer) mono_interp_to_native_trampoline), error); @@ -1535,6 +1545,7 @@ ves_pinvoke_method ( entry_func = get_interp_to_native_trampoline (); #endif mono_memory_barrier (); + MONO_EXIT_GC_UNSAFE; } #ifdef ENABLE_NETCORE -- 2.7.4