Fix issue where loaded global modules aren't freed
authorCry-Miron <31213913+Cry-Miron@users.noreply.github.com>
Tue, 12 Sep 2017 09:45:03 +0000 (11:45 +0200)
committerGitHub <noreply@github.com>
Tue, 12 Sep 2017 09:45:03 +0000 (11:45 +0200)
Globally loaded modules would previously call LoadLibrary on Windows, but never FreeLibrary. This would result in said library keeping an internal reference counter of 1 until the application exited its entry-point, resulting in possible shutdown issues.

This commit makes sure that we correctly free modules (and unload them in the platform-specific APIs) whenever Mono itself is shutting down, ensuring the expected result of Mono-loaded libraries being correctly freed.

mono/metadata/loader.c

index 85b5639384b1e70c1ac590fc5dd5d3108ea336d0..b41742ab7372d825a37a3cde7dd83d3b2cbfc2a0 100644 (file)
@@ -74,6 +74,7 @@ static gint32 signatures_size;
 MonoNativeTlsKey loader_lock_nest_id;
 
 static void dllmap_cleanup (void);
+static void cached_module_cleanup(void);
 
 static void
 global_loader_data_lock (void)
@@ -117,6 +118,7 @@ void
 mono_loader_cleanup (void)
 {
        dllmap_cleanup ();
+       cached_module_cleanup ();
 
        mono_native_tls_free (loader_lock_nest_id);
 
@@ -1137,6 +1139,21 @@ mono_loader_register_module (const char *name, MonoDl *module)
        g_hash_table_insert (global_module_map, g_strdup (name), module);
 }
 
+static void
+remove_cached_module(gpointer key, gpointer value, gpointer user_data)
+{
+       mono_dl_close((MonoDl*)value);
+}
+
+static void
+cached_module_cleanup(void)
+{
+       g_hash_table_foreach(global_module_map, remove_cached_module, NULL);
+
+       g_hash_table_destroy(global_module_map);
+       global_module_map = NULL;
+}
+
 static MonoDl *internal_module;
 
 static gboolean