Merge pull request #298 from ermshiperete/4921
[mono.git] / mono / mini / mini-exceptions.c
index 718696852f7c3aee1652c68552da17f54e1022dc..2da4058d2985e3f1e18efe9efef8799323400984 100644 (file)
@@ -433,11 +433,36 @@ get_generic_info_from_stack_frame (MonoJitInfo *ji, MonoContext *ctx)
        if (!gi->has_this)
                return NULL;
 
-       if (gi->this_in_reg)
-               info = (gpointer)mono_arch_context_get_int_reg (ctx, gi->this_reg);
-       else
-               info = *(gpointer*)(gpointer)((char*)mono_arch_context_get_int_reg (ctx, gi->this_reg) +
-                                                                         gi->this_offset);
+       info = NULL;
+       /*
+        * Search location list if available, it contains the precise location of the
+        * argument for every pc offset, even if the method was interrupted while it was in
+        * its prolog.
+        */
+       if (gi->nlocs) {
+               int offset = (mgreg_t)MONO_CONTEXT_GET_IP (ctx) - (mgreg_t)ji->code_start;
+               int i;
+
+               for (i = 0; i < gi->nlocs; ++i) {
+                       MonoDwarfLocListEntry *entry = &gi->locations [i];
+
+                       if (offset >= entry->from && (offset < entry->to || entry->to == 0)) {
+                               if (entry->is_reg)
+                                       info = (gpointer)mono_arch_context_get_int_reg (ctx, entry->reg);
+                               else
+                                       info = *(gpointer*)(gpointer)((char*)mono_arch_context_get_int_reg (ctx, entry->reg) + entry->offset);
+                               break;
+                       }
+               }
+               g_assert (i < gi->nlocs);
+       } else {
+               if (gi->this_in_reg)
+                       info = (gpointer)mono_arch_context_get_int_reg (ctx, gi->this_reg);
+               else
+                       info = *(gpointer*)(gpointer)((char*)mono_arch_context_get_int_reg (ctx, gi->this_reg) +
+                                                                                 gi->this_offset);
+       }
+
        if (mono_method_get_context (ji->method)->method_inst) {
                return info;
        } else if ((ji->method->flags & METHOD_ATTRIBUTE_STATIC) || ji->method->klass->valuetype) {
@@ -1912,6 +1937,8 @@ mono_setup_altstack (MonoJitTlsData *tls)
        sa.ss_flags = SS_ONSTACK;
 #endif
        g_assert (sigaltstack (&sa, NULL) == 0);
+
+       mono_gc_register_altstack ((char*)tls->stack_ovf_guard_base + tls->stack_ovf_guard_size, (char*)staddr + stsize - ((char*)tls->stack_ovf_guard_base + tls->stack_ovf_guard_size), tls->signal_stack, tls->signal_stack_size);
 }
 
 void
@@ -2191,7 +2218,7 @@ mono_handle_native_sigsegv (int signal, void *ctx)
        if (jit_tls && mono_thread_internal_current ()) {
                fprintf (stderr, "Stacktrace:\n\n");
 
-               mono_walk_stack (print_stack_frame, MONO_UNWIND_SIGNAL_SAFE, stderr);
+               mono_walk_stack (print_stack_frame, TRUE, stderr);
 
                fflush (stderr);
        }