[w32handle] Initialize them earlier
authorLudovic Henry <ludovic@xamarin.com>
Wed, 24 Aug 2016 10:09:08 +0000 (12:09 +0200)
committerLudovic Henry <ludovic@xamarin.com>
Wed, 24 Aug 2016 14:39:15 +0000 (16:39 +0200)
If we happen to have the debugger or the log profiler enabled, we would run into a use before initialization case for the w32handle. The debugger or profiler would call `mono_gc_base_init` which would attach the current thread, and that would crash in `mono_w32handle_new` at w32handle.c:437 with `scan_mutex` being an invalid value (EINVAL).

mono/metadata/domain.c
mono/mini/driver.c
mono/mini/mini-runtime.c
mono/utils/w32handle.c

index d564151b7df43e403c7a72cb7f58ca3810e3a468..0ceac2d500a98698255e82d3f9cff616c21dc88e 100644 (file)
@@ -43,7 +43,6 @@
 #include <metadata/threads.h>
 #include <metadata/profiler-private.h>
 #include <mono/metadata/coree.h>
-#include <mono/utils/w32handle.h>
 
 //#define DEBUG_DOMAIN_UNLOAD 1
 
@@ -526,7 +525,6 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
 #endif
 
 #ifndef HOST_WIN32
-       mono_w32handle_init ();
        wapi_init ();
 #endif
 
@@ -895,7 +893,6 @@ mono_cleanup (void)
 
 #ifndef HOST_WIN32
        wapi_cleanup ();
-       mono_w32handle_cleanup ();
 #endif
 }
 
index 5aa7153a506a1b4299ba1952be8752eab679e982..bd6e19fc4f50a07f60071c1ecd484b9cd3db2a60 100644 (file)
@@ -52,6 +52,7 @@
 #include "mono/utils/mono-counters.h"
 #include "mono/utils/mono-hwcap.h"
 #include "mono/utils/mono-logger-internals.h"
+#include "mono/utils/w32handle.h"
 
 #include "mini.h"
 #include "jit.h"
@@ -1962,6 +1963,10 @@ mono_main (int argc, char* argv[])
 
        mono_counters_init ();
 
+#ifndef HOST_WIN32
+       mono_w32handle_init ();
+#endif
+
        /* Set rootdir before loading config */
        mono_set_rootdir ();
 
index 857f52ea70ba7353ffbd0ab1a32b6225d63fc87a..5c88487a9180aa66ef565f1ce98acca91d048a54 100644 (file)
@@ -65,6 +65,7 @@
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/mono-threads-coop.h>
 #include <mono/utils/checked-build.h>
+#include <mono/utils/w32handle.h>
 #include <mono/io-layer/io-layer.h>
 
 #include "mini.h"
@@ -3569,6 +3570,10 @@ mini_init (const char *filename, const char *runtime_version)
 
        mono_counters_init ();
 
+#ifndef HOST_WIN32
+       mono_w32handle_init ();
+#endif
+
        mono_threads_runtime_init (&ticallbacks);
 
        if (g_getenv ("MONO_DEBUG") != NULL)
@@ -4109,6 +4114,10 @@ mini_cleanup (MonoDomain *domain)
        mono_os_mutex_destroy (&jit_mutex);
 
        mono_code_manager_cleanup ();
+
+#ifndef HOST_WIN32
+       mono_w32handle_cleanup ();
+#endif
 }
 
 void
index eabf26720126078a3e1deb7748b6ecc459142d7d..bd98e37b702d157ae473d84c26e873e248f5c32c 100644 (file)
@@ -293,6 +293,11 @@ mono_w32handle_unlock_handle (gpointer handle)
 void
 mono_w32handle_init (void)
 {
+       static gboolean initialized = FALSE;
+
+       if (initialized)
+               return;
+
        g_assert ((sizeof (handle_ops) / sizeof (handle_ops[0]))
                  == MONO_W32HANDLE_COUNT);
 
@@ -313,6 +318,8 @@ mono_w32handle_init (void)
 
        mono_os_cond_init (&global_signal_cond);
        mono_os_mutex_init (&global_signal_mutex);
+
+       initialized = TRUE;
 }
 
 static void mono_w32handle_unref_full (gpointer handle, gboolean ignore_private_busy_handles);