From 0256888233cf0d94443689f0abb508af11411033 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 21 Mar 2017 16:39:16 -0400 Subject: [PATCH] [runtime] Use coop handles for ves_icall_System_AppDomain_DoUnhandledException --- mono/metadata/appdomain-icalls.h | 2 +- mono/metadata/appdomain.c | 6 ++-- mono/metadata/icall-def.h | 2 +- mono/metadata/object-internals.h | 3 ++ mono/metadata/object.c | 53 +++++++++++++++++++++++--------- 5 files changed, 48 insertions(+), 18 deletions(-) diff --git a/mono/metadata/appdomain-icalls.h b/mono/metadata/appdomain-icalls.h index 0554aaaf622..d0e3345ad4b 100644 --- a/mono/metadata/appdomain-icalls.h +++ b/mono/metadata/appdomain-icalls.h @@ -75,7 +75,7 @@ ves_icall_System_AppDomain_InternalUnload (gint32 domain_id, MonoError *error); void -ves_icall_System_AppDomain_DoUnhandledException (MonoException *exc); +ves_icall_System_AppDomain_DoUnhandledException (MonoExceptionHandle exc, MonoError *error); gint32 ves_icall_System_AppDomain_ExecuteAssembly (MonoAppDomainHandle ad, diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c index 89b5584640f..98463194912 100644 --- a/mono/metadata/appdomain.c +++ b/mono/metadata/appdomain.c @@ -2246,9 +2246,11 @@ ves_icall_System_AppDomain_InternalIsFinalizingForUnload (gint32 domain_id, Mono } void -ves_icall_System_AppDomain_DoUnhandledException (MonoException *exc) +ves_icall_System_AppDomain_DoUnhandledException (MonoExceptionHandle exc, MonoError *error) { - mono_unhandled_exception ((MonoObject*) exc); + error_init (error); + mono_unhandled_exception_checked (MONO_HANDLE_CAST (MonoObject, exc), error); + mono_error_assert_ok (error); } gint32 diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index 85d6e53d70d..12617c755f5 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -115,7 +115,7 @@ ICALL(KPAIR_5, "_ProtectUser", ves_icall_Mono_Security_Cryptography_KeyPairPersi #endif /* !PLATFORM_RO_FS */ ICALL_TYPE(APPDOM, "System.AppDomain", APPDOM_23) -ICALL(APPDOM_23, "DoUnhandledException", ves_icall_System_AppDomain_DoUnhandledException) +HANDLES(ICALL(APPDOM_23, "DoUnhandledException", ves_icall_System_AppDomain_DoUnhandledException)) HANDLES(ICALL(APPDOM_1, "ExecuteAssembly", ves_icall_System_AppDomain_ExecuteAssembly)) HANDLES(ICALL(APPDOM_2, "GetAssemblies", ves_icall_System_AppDomain_GetAssemblies)) HANDLES(ICALL(APPDOM_3, "GetData", ves_icall_System_AppDomain_GetData)) diff --git a/mono/metadata/object-internals.h b/mono/metadata/object-internals.h index 48bf20f157e..61e06f7baae 100644 --- a/mono/metadata/object-internals.h +++ b/mono/metadata/object-internals.h @@ -1637,6 +1637,9 @@ mono_runtime_unhandled_exception_policy_get (void); void mono_runtime_unhandled_exception_policy_set (MonoRuntimeUnhandledExceptionPolicy policy); +void +mono_unhandled_exception_checked (MonoObjectHandle exc, MonoError *error); + MonoVTable * mono_class_try_get_vtable (MonoDomain *domain, MonoClass *klass); diff --git a/mono/metadata/object.c b/mono/metadata/object.c index 8b2d7353599..ae6b5d774e3 100644 --- a/mono/metadata/object.c +++ b/mono/metadata/object.c @@ -4487,16 +4487,41 @@ mono_runtime_unhandled_exception_policy_get (void) { * a warning to the console */ void -mono_unhandled_exception (MonoObject *exc) +mono_unhandled_exception (MonoObject *exc_raw) +{ + MonoError error; + HANDLE_FUNCTION_ENTER (); + MONO_HANDLE_DCL (MonoObject, exc); + error_init (&error); + mono_unhandled_exception_checked (exc, &error); + mono_error_assert_ok (&error); + HANDLE_FUNCTION_RETURN (); +} + +/** + * mono_unhandled_exception: + * @exc: exception thrown + * + * This is a VM internal routine. + * + * We call this function when we detect an unhandled exception + * in the default domain. + * + * It invokes the * UnhandledException event in AppDomain or prints + * a warning to the console + */ +void +mono_unhandled_exception_checked (MonoObjectHandle exc, MonoError *error) { MONO_REQ_GC_UNSAFE_MODE; - MonoError error; + error_init (error); MonoClassField *field; MonoDomain *current_domain, *root_domain; - MonoObject *current_appdomain_delegate = NULL, *root_appdomain_delegate = NULL; + MonoObjectHandle current_appdomain_delegate = MONO_HANDLE_NEW (MonoObject, NULL); - if (mono_class_has_parent (exc->vtable->klass, mono_defaults.threadabortexception_class)) + MonoClass *klass = mono_handle_class (exc); + if (mono_class_has_parent (klass, mono_defaults.threadabortexception_class)) return; field = mono_class_get_field_from_name (mono_defaults.appdomain_class, "UnhandledException"); @@ -4505,22 +4530,22 @@ mono_unhandled_exception (MonoObject *exc) current_domain = mono_domain_get (); root_domain = mono_get_root_domain (); - root_appdomain_delegate = mono_field_get_value_object_checked (root_domain, field, (MonoObject*) root_domain->domain, &error); - mono_error_assert_ok (&error); + MonoObjectHandle root_appdomain_delegate = MONO_HANDLE_NEW (MonoObject, mono_field_get_value_object_checked (root_domain, field, (MonoObject*) root_domain->domain, error)); /* FIXME use handles for mono_field_get_value_object_checked */ + return_if_nok (error); if (current_domain != root_domain) { - current_appdomain_delegate = mono_field_get_value_object_checked (current_domain, field, (MonoObject*) current_domain->domain, &error); - mono_error_assert_ok (&error); + MONO_HANDLE_ASSIGN (current_appdomain_delegate, MONO_HANDLE_NEW (MonoObject, mono_field_get_value_object_checked (current_domain, field, (MonoObject*) current_domain->domain, error))); /* FIXME use handles for mono_field_get_value_object_checked */ + return_if_nok (error); } - if (!current_appdomain_delegate && !root_appdomain_delegate) { - mono_print_unhandled_exception (exc); + if (MONO_HANDLE_IS_NULL (current_appdomain_delegate) && MONO_HANDLE_IS_NULL (root_appdomain_delegate)) { + mono_print_unhandled_exception (MONO_HANDLE_RAW (exc)); /* FIXME use handles for mono_print_unhandled_exception */ } else { /* unhandled exception callbacks must not be aborted */ mono_threads_begin_abort_protected_block (); - if (root_appdomain_delegate) - call_unhandled_exception_delegate (root_domain, root_appdomain_delegate, exc); - if (current_appdomain_delegate) - call_unhandled_exception_delegate (current_domain, current_appdomain_delegate, exc); + if (!MONO_HANDLE_IS_NULL (root_appdomain_delegate)) + call_unhandled_exception_delegate (root_domain, MONO_HANDLE_RAW (root_appdomain_delegate), MONO_HANDLE_RAW (exc)); /* FIXME use handles in call_unhandled_exception_delegate */ + if (!MONO_HANDLE_IS_NULL (current_appdomain_delegate)) + call_unhandled_exception_delegate (current_domain, MONO_HANDLE_RAW (current_appdomain_delegate), MONO_HANDLE_RAW (exc)); mono_threads_end_abort_protected_block (); } -- 2.25.1