2008-09-28 Zoltan Varga <vargaz@gmail.com>
+ * driver.c (mono_main): Add a workaround for shutdown crashes seen on
+ amd64, where the libc stack unwinder encounters stack frames referring to
+ native code in unmapped memory.
+
* method-to-ir.c (mini_emit_check_array_type): Add support for generic
sharing.
main_thread_handler (&main_args);
mono_thread_manage ();
#endif
+
+ /*
+ * On unix, WaitForMultipleObjects for threads is implemented by waiting on
+ * a cond variable, which is set by the thread when it exits _mono code_,
+ * but it could still be running libc code. On amd64, the libc thread exit
+ * code does a stack unwind, and if it encounters a frame pointing to native
+ * code which is in memory which is no longer mapped (because the runtime has
+ * shut down), it will crash:
+ * http://mail-archives.apache.org/mod_mbox/harmony-dev/200801.mbox/%3C200801130327.41572.gshimansky@apache.org%3E
+ * Testcase: tests/main-exit-background-change.exe.
+ * To make this race less frequent, we avoid freeing the global code manager.
+ * Since mono_main () is hopefully only used by the runtime executable, this
+ * will only cause a shutdown leak. This workaround also has the advantage
+ * that it can be back-ported to 2.0 safely.
+ * FIXME: Fix this properly by waiting for threads to really exit using
+ * pthread_join (). This cannot be done currently as the io-layer calls
+ * pthread_detach ().
+ */
+#ifdef __x86_64__
+ mono_dont_free_global_codeman = TRUE;
+#endif
+
mini_cleanup (domain);
/* Look up return value from System.Environment.ExitCode */
/* Whenever to disable passing/returning small valuetypes in registers for managed methods */
gboolean disable_vtypes_in_regs = FALSE;
+gboolean mono_dont_free_global_codeman;
+
#ifdef DISABLE_JIT
/* Define this here, since many files reference it */
const guint8 mono_burg_arity [MBMAX_OPCODES] = {
mono_trampolines_cleanup ();
- mono_code_manager_destroy (global_codeman);
+ if (!mono_dont_free_global_codeman)
+ mono_code_manager_destroy (global_codeman);
g_hash_table_destroy (jit_icall_name_hash);
g_free (emul_opcode_map);
extern gboolean check_for_pending_exc;
extern gboolean disable_vtypes_in_regs;
extern gboolean mono_verify_all;
+extern gboolean mono_dont_free_global_codeman;
#define INS_INFO(opcode) (&ins_info [((opcode) - OP_START - 1) * 3])