Fix crashes in the precise stack marking code if a thread is interrupted during startup.
authorZoltan Varga <vargaz@gmail.com>
Thu, 5 Jan 2012 16:06:37 +0000 (17:06 +0100)
committerZoltan Varga <vargaz@gmail.com>
Thu, 5 Jan 2012 16:07:19 +0000 (17:07 +0100)
mono/mini/mini-gc.c

index fd2a8536b9330d9daa28a1c7a83cba1ccb0a4c2a..16ca226843e0dd61c3912dfad98c417b82bbb4a6 100644 (file)
@@ -568,9 +568,11 @@ thread_suspend_func (gpointer user_data, void *sigctx)
 {
        TlsData *tls = user_data;
 
-       if (!tls)
+       if (!tls) {
                /* Happens during startup */
+               tls->unwind_state.valid = FALSE;
                return;
+       }
 
        if (tls->tid != GetCurrentThreadId ()) {
                /* Happens on osx because threads are not suspended using signals */
@@ -590,6 +592,12 @@ thread_suspend_func (gpointer user_data, void *sigctx)
                tls->unwind_state.unwind_data [MONO_UNWIND_DATA_JIT_TLS] = mono_native_tls_get_value (mono_jit_tls_id);
                tls->unwind_state.unwind_data [MONO_UNWIND_DATA_DOMAIN] = mono_domain_get ();
        }
+
+       if (!tls->unwind_state.unwind_data [MONO_UNWIND_DATA_DOMAIN]) {
+               /* Happens during startup */
+               tls->unwind_state.valid = FALSE;
+               return;
+       }
 }
 
 #define DEAD_REF ((gpointer)(gssize)0x2a2a2a2a2a2a2a2aULL)
@@ -714,6 +722,9 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
        memset (new_reg_locations, 0, sizeof (new_reg_locations));
 
        while (TRUE) {
+               if (!tls->unwind_state.valid)
+                       break;
+
                memcpy (&ctx, &new_ctx, sizeof (ctx));
 
                for (i = 0; i < MONO_MAX_IREGS; ++i) {
@@ -1042,6 +1053,9 @@ precise_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
        if (!tls)
                return;
 
+       if (!tls->unwind_state.valid)
+               return;
+
        for (findex = 0; findex < tls->nframes; findex ++) {
                /* Load information saved by the !precise pass */
                fi = &tls->frames [findex];