From ffd89bf04a5fd2b987d0e21c92482b746426d674 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Wed, 17 Jul 2019 14:44:50 +0200 Subject: [PATCH] [netcore] Clear system last error before P/Invoke calls with SetLastError=true (mono/mono#15703) Fixes mono/mono#15691 Commit migrated from https://github.com/mono/mono/commit/9af45e09db9c0d9813be46cd89d7c5092ea9600b --- src/mono/mono/metadata/jit-icall-reg.h | 1 + src/mono/mono/metadata/marshal.c | 12 ++++++++++++ src/mono/mono/metadata/marshal.h | 3 +++ src/mono/mono/mini/aot-runtime.h | 2 +- src/mono/mono/mini/interp/interp.c | 11 +++++++++++ src/mono/mono/mini/method-to-ir.c | 6 ++++++ 6 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/jit-icall-reg.h b/src/mono/mono/metadata/jit-icall-reg.h index da3d5b3..c48724c 100644 --- a/src/mono/mono/metadata/jit-icall-reg.h +++ b/src/mono/mono/metadata/jit-icall-reg.h @@ -234,6 +234,7 @@ MONO_JIT_ICALL (mono_llvmonly_init_delegate) \ MONO_JIT_ICALL (mono_llvmonly_init_delegate_virtual) \ MONO_JIT_ICALL (mono_marshal_asany) \ MONO_JIT_ICALL (mono_marshal_check_domain_image) \ +MONO_JIT_ICALL (mono_marshal_clear_last_error) \ MONO_JIT_ICALL (mono_marshal_free) \ MONO_JIT_ICALL (mono_marshal_free_array) \ MONO_JIT_ICALL (mono_marshal_free_asany) \ diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 5c22da4..4d19383 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -231,6 +231,7 @@ mono_marshal_init (void) register_icall (mono_marshal_free, mono_icall_sig_void_ptr, FALSE); register_icall (mono_marshal_set_last_error, mono_icall_sig_void, TRUE); register_icall (mono_marshal_set_last_error_windows, mono_icall_sig_void_int32, TRUE); + register_icall (mono_marshal_clear_last_error, mono_icall_sig_void, TRUE); register_icall (mono_string_utf8_to_builder, mono_icall_sig_void_ptr_ptr, FALSE); register_icall (mono_string_utf8_to_builder2, mono_icall_sig_object_ptr, FALSE); register_icall (mono_string_utf16_to_builder, mono_icall_sig_void_ptr_ptr, FALSE); @@ -5018,6 +5019,17 @@ mono_marshal_set_last_error_windows (int error) #endif } +void +mono_marshal_clear_last_error (void) +{ + /* This icall is called just before a P/Invoke call. */ +#ifdef WIN32 + SetLastError (ERROR_SUCCESS); +#else + errno = 0; +#endif +} + static gsize copy_managed_common (MonoArrayHandle managed, gconstpointer native, gint32 start_index, gint32 length, gpointer *managed_addr, guint32 *gchandle, MonoError *error) diff --git a/src/mono/mono/metadata/marshal.h b/src/mono/mono/metadata/marshal.h index 7501b68..89697d2 100644 --- a/src/mono/mono/metadata/marshal.h +++ b/src/mono/mono/metadata/marshal.h @@ -376,6 +376,9 @@ mono_marshal_ftnptr_eh_callback (guint32 gchandle); MONO_PAL_API void mono_marshal_set_last_error (void); +void +mono_marshal_clear_last_error (void); + guint mono_type_to_ldind (MonoType *type); diff --git a/src/mono/mono/mini/aot-runtime.h b/src/mono/mono/mini/aot-runtime.h index c31cb30..dd0bce5 100644 --- a/src/mono/mono/mini/aot-runtime.h +++ b/src/mono/mono/mini/aot-runtime.h @@ -11,7 +11,7 @@ #include "mini.h" /* Version number of the AOT file format */ -#define MONO_AOT_FILE_VERSION 167 +#define MONO_AOT_FILE_VERSION 168 #define MONO_AOT_TRAMP_PAGE_SIZE 16384 diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 7225daa..198992c 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -1364,6 +1364,12 @@ ves_pinvoke_method (InterpFrame *frame, MonoMethodSignature *sig, MonoFuncV addr mono_memory_barrier (); } +#ifdef ENABLE_NETCORE + if (save_last_error) { + mono_marshal_clear_last_error (); + } +#endif + #ifdef MONO_ARCH_HAVE_INTERP_PINVOKE_TRAMP CallContext ccontext; mono_arch_set_native_call_context_args (&ccontext, frame, sig); @@ -1874,6 +1880,11 @@ interp_entry (InterpEntryData *data) static stackval * do_icall (InterpFrame *frame, MonoMethodSignature *sig, int op, stackval *sp, gpointer ptr, gboolean save_last_error) { +#ifdef ENABLE_NETCORE + if (save_last_error) + mono_marshal_clear_last_error (); +#endif + switch (op) { case MINT_ICALL_V_V: { typedef void (*T)(void); diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 73cd37f..ff048d3 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -7386,6 +7386,12 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } } +#ifdef ENABLE_NETCORE + if (save_last_error) { + mono_emit_jit_icall (cfg, mono_marshal_clear_last_error, NULL); + } +#endif + /* Tail prefix / tailcall optimization */ /* FIXME: Enabling TAILC breaks some inlining/stack trace/etc tests. -- 2.7.4