Merge pull request #2493 from ludovic-henry/monoerror-mono_thread_attach_full
[mono.git] / mono / metadata / appdomain.c
index 184fb62150895e0498f046c6f032517dd8c2d825..f87fc81dc08e2a5c0fc7e06210caa4f8688ff76e 100644 (file)
@@ -110,7 +110,7 @@ static void
 add_assemblies_to_domain (MonoDomain *domain, MonoAssembly *ass, GHashTable *hash);
 
 static MonoAppDomain *
-mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *setup);
+mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *setup, MonoError *error);
 
 static char *
 get_shadow_assembly_location_base (MonoDomain *domain, MonoError *error);
@@ -278,7 +278,7 @@ mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb,
 
        /* mscorlib is loaded before we install the load hook */
        mono_domain_fire_assembly_load (mono_defaults.corlib->assembly, NULL);
-       
+
        return;
 }
 
@@ -392,6 +392,7 @@ mono_runtime_quit ()
 MonoDomain *
 mono_domain_create_appdomain (char *friendly_name, char *configuration_file)
 {
+       MonoError error;
        MonoAppDomain *ad;
        MonoAppDomainSetup *setup;
        MonoClass *klass;
@@ -400,7 +401,8 @@ mono_domain_create_appdomain (char *friendly_name, char *configuration_file)
        setup = (MonoAppDomainSetup *) mono_object_new (mono_domain_get (), klass);
        setup->configuration_file = configuration_file != NULL ? mono_string_new (mono_domain_get (), configuration_file) : NULL;
 
-       ad = mono_domain_create_appdomain_internal (friendly_name, setup);
+       ad = mono_domain_create_appdomain_internal (friendly_name, setup, &error);
+       mono_error_raise_exception (&error); /* FIXME don't raise here */
 
        return mono_domain_from_appdomain (ad);
 }
@@ -460,14 +462,13 @@ copy_app_domain_setup (MonoDomain *domain, MonoAppDomainSetup *setup)
 }
 
 static MonoAppDomain *
-mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *setup)
+mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *setup, MonoError *error)
 {
-       MonoError error;
        MonoClass *adclass;
        MonoAppDomain *ad;
        MonoDomain *data;
        char *shadow_location;
-       
+
        adclass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomain");
 
        /* FIXME: pin all those objects */
@@ -490,14 +491,15 @@ mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *
        mono_context_init (data);
 
        data->setup = copy_app_domain_setup (data, setup);
-       mono_set_private_bin_path_from_config (data);
+       mono_domain_set_options_from_config (data);
        add_assemblies_to_domain (data, mono_defaults.corlib->assembly, NULL);
 
 #ifndef DISABLE_SHADOW_COPY
        /*FIXME, guard this for when the debugger is not running */
-       shadow_location = get_shadow_assembly_location_base (data, &error);
-       if (!mono_error_ok (&error))
-               mono_error_raise_exception (&error);
+       shadow_location = get_shadow_assembly_location_base (data, error);
+       if (!mono_error_ok (error))
+               return NULL;
+
        g_free (shadow_location);
 #endif
 
@@ -710,6 +712,14 @@ ves_icall_System_AppDomain_getRootDomain ()
        return root->domain;
 }
 
+MonoBoolean
+ves_icall_System_CLRConfig_CheckThrowUnobservedTaskExceptions ()
+{
+       MonoDomain *domain = mono_domain_get ();
+
+       return domain->throw_unobserved_task_exceptions;
+}
+
 static char*
 get_attribute_value (const gchar **attribute_names, 
                     const gchar **attribute_values, 
@@ -742,8 +752,18 @@ start_element (GMarkupParseContext *context,
                runtime_config->assemblybinding_count++;
                return;
        }
-       
-       if (runtime_config->runtime_count != 1 || runtime_config->assemblybinding_count != 1)
+
+       if (runtime_config->runtime_count != 1)
+               return;
+
+       if (strcmp (element_name, "ThrowUnobservedTaskExceptions") == 0) {
+               const char *value = get_attribute_value (attribute_names, attribute_values, "enabled");
+
+               if (value && g_ascii_strcasecmp (value, "true") == 0)
+                       runtime_config->domain->throw_unobserved_task_exceptions = TRUE;
+       }
+
+       if (runtime_config->assemblybinding_count != 1)
                return;
 
        if (strcmp (element_name, "probing") != 0)
@@ -793,7 +813,7 @@ mono_parser = {
 };
 
 void
-mono_set_private_bin_path_from_config (MonoDomain *domain)
+mono_domain_set_options_from_config (MonoDomain *domain)
 {
        MonoError error;
        gchar *config_file_name = NULL, *text = NULL, *config_file_path = NULL;
@@ -846,11 +866,17 @@ ves_icall_System_AppDomain_createDomain (MonoString *friendly_name, MonoAppDomai
        mono_set_pending_exception (mono_get_exception_not_supported ("AppDomain creation is not supported on this runtime."));
        return NULL;
 #else
-       char *fname = mono_string_to_utf8 (friendly_name);
-       MonoAppDomain *ad = mono_domain_create_appdomain_internal (fname, setup);
-       
+       MonoError error;
+       char *fname;
+       MonoAppDomain *ad;
+
+       fname = mono_string_to_utf8 (friendly_name);
+       ad = mono_domain_create_appdomain_internal (fname, setup, &error);
+
        g_free (fname);
 
+       mono_error_raise_exception (&error);
+
        return ad;
 #endif
 }
@@ -1231,8 +1257,9 @@ mono_is_shadow_copy_enabled (MonoDomain *domain, const gchar *dir_name)
 }
 
 char *
-mono_make_shadow_copy (const char *filename)
+mono_make_shadow_copy (const char *filename, MonoError *error)
 {
+       mono_error_init (error);
        return (char *) filename;
 }
 #else
@@ -1610,7 +1637,7 @@ or NULL if source file not found.
 FIXME bubble up the error instead of raising it here
 */
 char *
-mono_make_shadow_copy (const char *filename)
+mono_make_shadow_copy (const char *filename, MonoError *oerror)
 {
        MonoError error;
        gchar *sibling_source, *sibling_target;
@@ -1619,13 +1646,14 @@ mono_make_shadow_copy (const char *filename)
        guint32 attrs;
        char *shadow;
        gboolean copy_result;
-       MonoException *exc;
        struct stat src_sbuf;
        struct utimbuf utbuf;
        char *dir_name = g_path_get_dirname (filename);
        MonoDomain *domain = mono_domain_get ();
        char *shadow_dir;
 
+       mono_error_init (oerror);
+
        set_domain_search_path (domain);
 
        if (!mono_is_shadow_copy_enabled (domain, dir_name)) {
@@ -1638,8 +1666,8 @@ mono_make_shadow_copy (const char *filename)
        if (!mono_error_ok (&error)) {
                mono_error_cleanup (&error);
                g_free (dir_name);
-               exc = mono_get_exception_execution_engine ("Failed to create shadow copy (invalid characters in shadow directory name).");
-               mono_raise_exception (exc);
+               mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy (invalid characters in shadow directory name).");
+               return NULL;
        }
 
        if (strstr (dir_name, shadow_dir)) {
@@ -1653,14 +1681,14 @@ mono_make_shadow_copy (const char *filename)
        shadow = get_shadow_assembly_location (filename, &error);
        if (!mono_error_ok (&error)) {
                mono_error_cleanup (&error);
-               exc = mono_get_exception_execution_engine ("Failed to create shadow copy (invalid characters in file name).");
-               mono_raise_exception (exc);
+               mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy (invalid characters in file name).");
+               return NULL;
        }
 
        if (ensure_directory_exists (shadow) == FALSE) {
                g_free (shadow);
-               exc = mono_get_exception_execution_engine ("Failed to create shadow copy (ensure directory exists).");
-               mono_raise_exception (exc);
+               mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy (ensure directory exists).");
+               return NULL;
        }       
 
        if (!private_file_needs_copying (filename, &src_sbuf, shadow))
@@ -1696,8 +1724,8 @@ mono_make_shadow_copy (const char *filename)
                if (GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_PATH_NOT_FOUND)
                        return NULL; /* file not found, shadow copy failed */
 
-               exc = mono_get_exception_execution_engine ("Failed to create shadow copy (CopyFile).");
-               mono_raise_exception (exc);
+               mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy (CopyFile).");
+               return NULL;
        }
 
        /* attempt to copy .mdb, .config if they exist */
@@ -1715,15 +1743,15 @@ mono_make_shadow_copy (const char *filename)
        
        if (copy_result == FALSE)  {
                g_free (shadow);
-               exc = mono_get_exception_execution_engine ("Failed to create shadow copy of sibling data (CopyFile).");
-               mono_raise_exception (exc);
+               mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy of sibling data (CopyFile).");
+               return NULL;
        }
 
        /* Create a .ini file containing the original assembly location */
        if (!shadow_copy_create_ini (shadow, filename)) {
                g_free (shadow);
-               exc = mono_get_exception_execution_engine ("Failed to create shadow copy .ini file.");
-               mono_raise_exception (exc);
+               mono_error_set_generic_error (oerror, "System", "ExecutionEngineException", "Failed to create shadow copy .ini file.");
+               return NULL;
        }
 
        utbuf.actime = src_sbuf.st_atime;
@@ -2263,6 +2291,7 @@ deregister_reflection_info_roots (MonoDomain *domain)
 static guint32 WINAPI
 unload_thread_main (void *arg)
 {
+       MonoError error;
        unload_data *data = (unload_data*)arg;
        MonoDomain *domain = data->domain;
        MonoThread *thread;
@@ -2270,7 +2299,8 @@ unload_thread_main (void *arg)
 
        /* Have to attach to the runtime so shutdown can wait for this thread */
        /* Force it to be attached to avoid racing during shutdown. */
-       thread = mono_thread_attach_full (mono_get_root_domain (), TRUE);
+       thread = mono_thread_attach_full (mono_get_root_domain (), TRUE, &error);
+       mono_error_raise_exception (&error); /* FIXME don't raise here */
 
        /* 
         * FIXME: Abort our parent thread last, so we can return a failure