From: Vlad Brezae Date: Thu, 14 Sep 2017 23:34:26 +0000 (+0300) Subject: [runtime] Don't terminate application on unhandled AppDomainUnloadedException X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=b2cf1149023a9f5c44c176d2aa873719baa41b34 [runtime] Don't terminate application on unhandled AppDomainUnloadedException Except for threads started by unmanaged code (like the main thread). --- diff --git a/mono/metadata/class-internals.h b/mono/metadata/class-internals.h index 2b3a0b42aa3..f744fc1fdc4 100644 --- a/mono/metadata/class-internals.h +++ b/mono/metadata/class-internals.h @@ -1170,6 +1170,8 @@ GENERATE_GET_CLASS_WITH_CACHE_DECL (variant) #endif +GENERATE_GET_CLASS_WITH_CACHE_DECL (appdomain_unloaded_exception) + extern MonoDefaults mono_defaults; void diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c index 5281a5d39b8..a5ef34da2d6 100644 --- a/mono/metadata/loader.c +++ b/mono/metadata/loader.c @@ -76,6 +76,9 @@ MonoNativeTlsKey loader_lock_nest_id; static void dllmap_cleanup (void); static void cached_module_cleanup(void); +/* Class lazy loading functions */ +GENERATE_GET_CLASS_WITH_CACHE (appdomain_unloaded_exception, "System", "AppDomainUnloadedException") + static void global_loader_data_lock (void) { diff --git a/mono/metadata/object.c b/mono/metadata/object.c index 2ea88c75f8c..9ace3f66652 100644 --- a/mono/metadata/object.c +++ b/mono/metadata/object.c @@ -4587,7 +4587,14 @@ mono_unhandled_exception_checked (MonoObjectHandle exc, MonoError *error) MonoObjectHandle current_appdomain_delegate = MONO_HANDLE_NEW (MonoObject, NULL); MonoClass *klass = mono_handle_class (exc); - if (mono_class_has_parent (klass, mono_defaults.threadabortexception_class)) + /* + * AppDomainUnloadedException don't behave like unhandled exceptions unless thrown from + * a thread started in unmanaged world. + * https://msdn.microsoft.com/en-us/library/system.appdomainunloadedexception(v=vs.110).aspx#Anchor_6 + */ + if (klass == mono_defaults.threadabortexception_class || + (klass == mono_class_get_appdomain_unloaded_exception_class () && + mono_thread_info_current ()->runtime_thread)) return; field = mono_class_get_field_from_name (mono_defaults.appdomain_class, "UnhandledException"); diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c index f804fce2793..52dc0c0c230 100644 --- a/mono/metadata/threads.c +++ b/mono/metadata/threads.c @@ -199,9 +199,6 @@ static gboolean shutting_down = FALSE; static gint32 managed_thread_id_counter = 0; -/* Class lazy loading functions */ -static GENERATE_GET_CLASS_WITH_CACHE (appdomain_unloaded_exception, "System", "AppDomainUnloadedException") - static void mono_threads_lock (void) { diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index 5e6e3cd9cad..90d695ae2d6 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -890,7 +890,9 @@ mono_thread_abort (MonoObject *obj) g_free (jit_tls);*/ if ((mono_runtime_unhandled_exception_policy_get () == MONO_UNHANDLED_POLICY_LEGACY) || - (obj->vtable->klass == mono_defaults.threadabortexception_class)) { + (obj->vtable->klass == mono_defaults.threadabortexception_class) || + ((obj->vtable->klass) == mono_class_get_appdomain_unloaded_exception_class () && + mono_thread_info_current ()->runtime_thread)) { mono_thread_exit (); } else { mono_invoke_unhandled_exception_hook (obj);