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).
#include <metadata/threads.h>
#include <metadata/profiler-private.h>
#include <mono/metadata/coree.h>
-#include <mono/utils/w32handle.h>
//#define DEBUG_DOMAIN_UNLOAD 1
#endif
#ifndef HOST_WIN32
- mono_w32handle_init ();
wapi_init ();
#endif
#ifndef HOST_WIN32
wapi_cleanup ();
- mono_w32handle_cleanup ();
#endif
}
#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"
mono_counters_init ();
+#ifndef HOST_WIN32
+ mono_w32handle_init ();
+#endif
+
/* Set rootdir before loading config */
mono_set_rootdir ();
#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"
mono_counters_init ();
+#ifndef HOST_WIN32
+ mono_w32handle_init ();
+#endif
+
mono_threads_runtime_init (&ticallbacks);
if (g_getenv ("MONO_DEBUG") != NULL)
mono_os_mutex_destroy (&jit_mutex);
mono_code_manager_cleanup ();
+
+#ifndef HOST_WIN32
+ mono_w32handle_cleanup ();
+#endif
}
void
void
mono_w32handle_init (void)
{
+ static gboolean initialized = FALSE;
+
+ if (initialized)
+ return;
+
g_assert ((sizeof (handle_ops) / sizeof (handle_ops[0]))
== MONO_W32HANDLE_COUNT);
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);