X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fappdomain.c;h=e600fa57a80d36d35739cb345cd36df2f4f1b6e0;hb=a476d44787d5a8d2740ffe3b819ac1fce4491fb8;hp=21943000e177e98f85960c9f29ecd4b4335f8c87;hpb=09d4b9a9009d8fdff4bd983842587b283bbac027;p=mono.git diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c index 21943000e17..e600fa57a80 100644 --- a/mono/metadata/appdomain.c +++ b/mono/metadata/appdomain.c @@ -8,10 +8,11 @@ * * (c) 2001-2003 Ximian, Inc. (http://www.ximian.com) */ - +#undef ASSEMBLY_LOAD_DEBUG #include #include #include +#include #include @@ -28,9 +29,13 @@ #include #include #include +#include #include +#include +#include +#include -#define MONO_CORLIB_VERSION 41 +#define MONO_CORLIB_VERSION 54 CRITICAL_SECTION mono_delegate_section; @@ -200,7 +205,15 @@ mono_runtime_cleanup (MonoDomain *domain) /* This ends up calling any pending pending (for at most 2 seconds) */ mono_gc_cleanup (); + mono_thread_cleanup (); + mono_network_cleanup (); + + mono_marshal_cleanup (); + + mono_type_initialization_cleanup (); + + mono_monitor_cleanup (); } static MonoDomainFunc quit_function = NULL; @@ -349,13 +362,15 @@ mono_domain_set (MonoDomain *domain, gboolean force) MonoObject * ves_icall_System_AppDomain_GetData (MonoAppDomain *ad, MonoString *name) { - MonoDomain *add = ad->data; + MonoDomain *add; MonoObject *o; char *str; MONO_ARCH_SAVE_REGS; g_assert (ad != NULL); + add = ad->data; + g_assert (add != NULL); if (name == NULL) mono_raise_exception (mono_get_exception_argument_null ("name")); @@ -397,11 +412,13 @@ ves_icall_System_AppDomain_GetData (MonoAppDomain *ad, MonoString *name) void ves_icall_System_AppDomain_SetData (MonoAppDomain *ad, MonoString *name, MonoObject *data) { - MonoDomain *add = ad->data; + MonoDomain *add; MONO_ARCH_SAVE_REGS; g_assert (ad != NULL); + add = ad->data; + g_assert (add != NULL); if (name == NULL) mono_raise_exception (mono_get_exception_argument_null ("name")); @@ -458,11 +475,9 @@ ves_icall_System_AppDomain_getRootDomain () MonoAppDomain * ves_icall_System_AppDomain_createDomain (MonoString *friendly_name, MonoAppDomainSetup *setup) { - MonoDomain *domain = mono_domain_get (); MonoClass *adclass; MonoAppDomain *ad; MonoDomain *data; - GSList *tmp; MONO_ARCH_SAVE_REGS; @@ -481,17 +496,13 @@ ves_icall_System_AppDomain_createDomain (MonoString *friendly_name, MonoAppDomai if (!setup->application_base) { /* Inherit from the root domain since MS.NET does this */ MonoDomain *root = mono_get_root_domain (); - setup->application_base = mono_string_new_utf16 (data, mono_string_chars (root->setup->application_base), mono_string_length (root->setup->application_base)); + if (root->setup->application_base) + MONO_OBJECT_SETREF (setup, application_base, mono_string_new_utf16 (data, mono_string_chars (root->setup->application_base), mono_string_length (root->setup->application_base))); } mono_context_init (data); - /* The new appdomain should have all assemblies loaded */ - mono_domain_assemblies_lock (domain); - /*g_print ("copy assemblies from domain %p (%s)\n", domain, domain->friendly_name);*/ - for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) - add_assemblies_to_domain (data, tmp->data, NULL); - mono_domain_assemblies_unlock (domain); + add_assemblies_to_domain (data, mono_defaults.corlib->assembly, NULL); return ad; } @@ -530,7 +541,7 @@ ves_icall_System_AppDomain_GetAssemblies (MonoAppDomain *ad, MonoBoolean refonly continue; if (ass->corlib_internal) continue; - mono_array_set (res, gpointer, i, mono_assembly_get_object (domain, ass)); + mono_array_setref (res, i, mono_assembly_get_object (domain, ass)); ++i; } mono_domain_assemblies_unlock (domain); @@ -611,6 +622,7 @@ add_assemblies_to_domain (MonoDomain *domain, MonoAssembly *ass, GHashTable *ht) mono_assembly_addref (ass); g_hash_table_insert (ht, ass, ass); domain->domain_assemblies = g_slist_prepend (domain->domain_assemblies, ass); + mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Assembly %s %p added to domain %s, ref_count=%d\n", ass->aname.name, ass, domain->friendly_name, ass->ref_count); } if (ass->image->references) { @@ -638,7 +650,9 @@ mono_domain_fire_assembly_load (MonoAssembly *assembly, gpointer user_data) if (!domain->domain) /* This can happen during startup */ return; - +#ifdef ASSEMBLY_LOAD_DEBUG + fprintf (stderr, "Loading %s into domain %s\n", assembly->aname.name, domain->friendly_name); +#endif klass = domain->domain->mbr.obj.vtable->klass; mono_domain_assemblies_lock (domain); @@ -668,56 +682,6 @@ mono_domain_fire_assembly_load (MonoAssembly *assembly, gpointer user_data) mono_runtime_invoke (assembly_load_method, domain->domain, params, NULL); } -static gchar * -reduce_path (const gchar *dirname) -{ - gchar **parts; - gchar *part; - GList *list, *tmp; - GString *result; - gchar *res; - gint i; - - parts = g_strsplit (dirname, G_DIR_SEPARATOR_S, 0); - list = NULL; - for (i = 0; (part = parts [i]) != NULL; i++) { - if (!strcmp (part, ".")) - continue; - - if (!strcmp (part, "..")) { - if (list && list->next) /* Don't remove root */ - list = g_list_delete_link (list, list); - } else { - list = g_list_prepend (list, part); - } - } - - result = g_string_new (""); - list = g_list_reverse (list); - - for (tmp = list; tmp; tmp = tmp->next) { - gchar *data = (gchar *) tmp->data; - - if (data && *data) { -#ifdef PLATFORM_WIN32 - if (result->len == 0) - g_string_append_printf (result, "%s\\", data); - else if (result->str [result->len - 1] == '\\') - g_string_append_printf (result, "%s", data); - else -#endif - g_string_append_printf (result, "%c%s", - G_DIR_SEPARATOR, data); - } - } - - res = result->str; - g_string_free (result, FALSE); - g_list_free (list); - g_strfreev (parts); - return res; -} - static void set_domain_search_path (MonoDomain *domain) { @@ -805,7 +769,7 @@ set_domain_search_path (MonoDomain *domain) gchar *reduced; gchar *freeme; - reduced = reduce_path (tmp [i]); + reduced = mono_path_canonicalize (tmp [i]); if (appbaselen == -1) appbaselen = strlen (tmp [0]); @@ -832,16 +796,62 @@ set_domain_search_path (MonoDomain *domain) g_strfreev (pvt_split); } +static char * +make_shadow_copy (const char *filename) +{ + gchar *tmp; + guint16 *orig, *dest; + MonoDomain *domain = mono_domain_get (); + char *db; + int fd; + gboolean copy_result; + MonoException *exc; + + db = mono_string_to_utf8 (domain->setup->dynamic_base); + tmp = g_build_filename (db, "shadow-XXXXXX", NULL); + fd = mono_mkstemp (tmp); + if (fd == -1) { + exc = mono_get_exception_execution_engine ("Failed to create shadow copy (mkstemp)."); + g_free (tmp); + g_free (db); + mono_raise_exception (exc); + } + close (fd); + remove (tmp); + orig = g_utf8_to_utf16 (filename, strlen (filename), NULL, NULL, NULL); + dest = g_utf8_to_utf16 (tmp, strlen (tmp), NULL, NULL, NULL); + copy_result = CopyFile (orig, dest, TRUE); + g_free (dest); + g_free (orig); + g_free (db); + + if (copy_result == FALSE) { + g_free (tmp); + exc = mono_get_exception_execution_engine ("Failed to create shadow copy (CopyFile)."); + mono_raise_exception (exc); + } + return tmp; +} + static gboolean try_load_from (MonoAssembly **assembly, const gchar *path1, const gchar *path2, - const gchar *path3, const gchar *path4, gboolean refonly) + const gchar *path3, const gchar *path4, + gboolean refonly, gboolean is_private) { + gchar *fullpath; *assembly = NULL; fullpath = g_build_filename (path1, path2, path3, path4, NULL); - if (g_file_test (fullpath, G_FILE_TEST_IS_REGULAR)) + if (g_file_test (fullpath, G_FILE_TEST_IS_REGULAR)) { + if (is_private) { + char *new_path = make_shadow_copy (fullpath); + g_free (fullpath); + fullpath = new_path; + } + *assembly = mono_assembly_open_full (fullpath, NULL, refonly); + } g_free (fullpath); return (*assembly != NULL); @@ -855,6 +865,7 @@ real_load (gchar **search_path, const gchar *culture, const gchar *name, gboolea gchar *filename; const gchar *local_culture; gint len; + gboolean is_private = FALSE; if (!culture || *culture == '\0') { local_culture = ""; @@ -866,28 +877,30 @@ real_load (gchar **search_path, const gchar *culture, const gchar *name, gboolea len = strlen (filename); for (path = search_path; *path; path++) { - if (**path == '\0') + if (**path == '\0') { + is_private = TRUE; continue; /* Ignore empty ApplicationBase */ + } /* See test cases in bug #58992 and bug #57710 */ /* 1st try: [culture]/[name].dll (culture may be empty) */ strcpy (filename + len - 4, ".dll"); - if (try_load_from (&result, *path, local_culture, "", filename, refonly)) + if (try_load_from (&result, *path, local_culture, "", filename, refonly, is_private)) break; /* 2nd try: [culture]/[name].exe (culture may be empty) */ strcpy (filename + len - 4, ".exe"); - if (try_load_from (&result, *path, local_culture, "", filename, refonly)) + if (try_load_from (&result, *path, local_culture, "", filename, refonly, is_private)) break; /* 3rd try: [culture]/[name]/[name].dll (culture may be empty) */ strcpy (filename + len - 4, ".dll"); - if (try_load_from (&result, *path, local_culture, name, filename, refonly)) + if (try_load_from (&result, *path, local_culture, name, filename, refonly, is_private)) break; /* 4th try: [culture]/[name]/[name].exe (culture may be empty) */ strcpy (filename + len - 4, ".exe"); - if (try_load_from (&result, *path, local_culture, name, filename, refonly)) + if (try_load_from (&result, *path, local_culture, name, filename, refonly, is_private)) break; } @@ -967,13 +980,19 @@ ves_icall_System_Reflection_Assembly_LoadFrom (MonoString *fname, MonoBoolean re ass = mono_assembly_open_full (filename, &status, refOnly); - g_free (name); - if (!ass){ - MonoException *exc = mono_get_exception_file_not_found (fname); + MonoException *exc; + + if (status == MONO_IMAGE_IMAGE_INVALID) + exc = mono_get_exception_bad_image_format2 (NULL, fname); + else + exc = mono_get_exception_file_not_found2 (NULL, fname); + g_free (name); mono_raise_exception (exc); } + g_free (name); + return mono_assembly_get_object (domain, ass); } @@ -990,16 +1009,17 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomain *ad, guint32 raw_assembly_len = mono_array_length (raw_assembly); MonoImage *image = mono_image_open_from_data_full (mono_array_addr (raw_assembly, gchar, 0), raw_assembly_len, TRUE, NULL, refonly); - if (raw_symbol_store) - mono_raise_exception (mono_get_exception_not_implemented ("LoadAssemblyRaw: Raw Symbol Store not Implemented")); - if (!image) { mono_raise_exception (mono_get_exception_bad_image_format ("")); return NULL; } + if (raw_symbol_store != NULL) + mono_debug_init_2_memory (image, mono_array_addr (raw_symbol_store, guint8, 0), mono_array_length (raw_symbol_store)); + ass = mono_assembly_load_from_full (image, "", &status, refonly); + if (!ass) { mono_image_close (image); mono_raise_exception (mono_get_exception_bad_image_format ("")); @@ -1007,7 +1027,7 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomain *ad, } refass = mono_assembly_get_object (domain, ass); - refass->evidence = evidence; + MONO_OBJECT_SETREF (refass, evidence, evidence); return refass; } @@ -1034,7 +1054,7 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad, MonoString *assRef, MonoException *exc; /* This is a parse error... */ - exc = mono_get_exception_file_not_found (assRef); + exc = mono_get_exception_file_not_found2 (NULL, assRef); mono_raise_exception (exc); } @@ -1043,14 +1063,14 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad, MonoString *assRef, if (!ass && (refass = try_assembly_resolve (domain, assRef, refOnly)) == NULL){ /* FIXME: it doesn't make much sense since we really don't have a filename ... */ - MonoException *exc = mono_get_exception_file_not_found (assRef); + MonoException *exc = mono_get_exception_file_not_found2 (NULL, assRef); mono_raise_exception (exc); } if (refass == NULL) refass = mono_assembly_get_object (domain, ass); - refass->evidence = evidence; + MONO_OBJECT_SETREF (refass, evidence, evidence); return refass; } @@ -1110,7 +1130,7 @@ ves_icall_System_AppDomain_ExecuteAssembly (MonoAppDomain *ad, MonoString *file, g_free (filename); if (!assembly) - mono_raise_exception (mono_get_exception_file_not_found (file)); + mono_raise_exception (mono_get_exception_file_not_found2 (NULL, file)); image = assembly->image; @@ -1123,7 +1143,7 @@ ves_icall_System_AppDomain_ExecuteAssembly (MonoAppDomain *ad, MonoString *file, args = (MonoArray *) mono_array_new (ad->data, mono_defaults.string_class, 0); refass = mono_assembly_get_object (ad->data, assembly); - refass->evidence = evidence; + MONO_OBJECT_SETREF (refass, evidence, evidence); res = mono_runtime_exec_main (method, (MonoArray *)args, NULL); @@ -1304,6 +1324,9 @@ unload_thread_main (void *arg) /* printf ("UNLOADED %s.\n", domain->friendly_name); */ + /* remove from the handle table the items related to this domain */ + mono_gchandle_free_domain (domain); + mono_domain_free (domain, FALSE); mono_gc_collect (mono_gc_max_generation ()); @@ -1388,8 +1411,10 @@ mono_domain_unload (MonoDomain *domain) if (mono_thread_has_appdomain_ref (mono_thread_current (), domain) && (mono_thread_interruption_requested ())) /* The unload thread tries to abort us */ /* The icall wrapper will execute the abort */ + CloseHandle (thread_handle); return; } + CloseHandle (thread_handle); mono_domain_set (caller_domain, FALSE);