2008-09-28 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Sun, 28 Sep 2008 02:28:23 +0000 (02:28 -0000)
committerZoltan Varga <vargaz@gmail.com>
Sun, 28 Sep 2008 02:28:23 +0000 (02:28 -0000)
* 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.

svn path=/trunk/mono/; revision=114307

mono/mini/ChangeLog
mono/mini/driver.c
mono/mini/mini.c
mono/mini/mini.h

index 54d11409fc206d813a0d37efad1a004b1b8653f5..897ab99248d32dec53a805093fb4be920f4edb46 100644 (file)
@@ -1,5 +1,9 @@
 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.
 
index cd2abe9967e7d94f8af1ea5a37f55a15b12f6932..8de3e34b5c48bf542bf15b0ffbc48649d36c3543 100644 (file)
@@ -1629,6 +1629,28 @@ mono_main (int argc, char* argv[])
                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 */
index e56cf0af1153f5cc24db6757a4a483713257a211..b074740dc7456833ac2c336b2d7cab922a15acdc 100644 (file)
@@ -216,6 +216,8 @@ gboolean check_for_pending_exc = TRUE;
 /* 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] = {
@@ -14754,7 +14756,8 @@ mini_cleanup (MonoDomain *domain)
 
        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);
 
index 43d2cfd92531f4be2d5d7df378aff82300d4b68e..c014dacf1a36c7c4661ed5b949f1f677c0a368b8 100644 (file)
@@ -232,6 +232,7 @@ extern int mono_break_at_bb_bb_num;
 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])