[xbuild] Vbc task - make error column check a little non-specific.
[mono.git] / mono / mini / mini-exceptions.c
index 5576d41441835a1a14431232acb5600e1156c0a0..265f600171894fe27b0f5a1725bcade8ec068feb 100644 (file)
@@ -361,7 +361,7 @@ mono_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls,
                return FALSE;
 
        if (frame->type == FRAME_TYPE_MANAGED) {
-               if (!ji->method->wrapper_type || ji->method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD)
+               if (!frame->ji->method->wrapper_type || frame->ji->method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD)
                        frame->managed = TRUE;
        }
 
@@ -1329,6 +1329,9 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, gpointer obj, gpoin
                                        }
                                        g_list_free (trace_ips);
 
+                                       if (out_ji)
+                                               *out_ji = ji;
+
                                        /* mono_debugger_agent_handle_exception () needs this */
                                        MONO_CONTEXT_SET_IP (ctx, ei->handler_start);
                                        return TRUE;
@@ -1468,7 +1471,7 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gpointer origina
                mono_profiler_exception_thrown (obj);
                jit_tls->orig_ex_ctx_set = FALSE;
 
-               res = mono_handle_exception_internal_first_pass (&ctx_cp, obj, original_ip, &first_filter_idx, out_ji, non_exception);
+               res = mono_handle_exception_internal_first_pass (&ctx_cp, obj, original_ip, &first_filter_idx, &ji, non_exception);
 
                if (!res) {
                        if (mono_break_on_exc)
@@ -1485,7 +1488,14 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gpointer origina
                        // we are handling a stack overflow
                        mono_unhandled_exception (obj);
                } else {
-                       mono_debugger_agent_handle_exception (obj, ctx, &ctx_cp);
+                       //
+                       // Treat exceptions that are "handled" by mono_runtime_invoke() as unhandled.
+                       // See bug #669836.
+                       //
+                       if (ji && ji->method->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE)
+                               mono_debugger_agent_handle_exception (obj, ctx, NULL);
+                       else
+                               mono_debugger_agent_handle_exception (obj, ctx, &ctx_cp);
                }
        }
 
@@ -2003,6 +2013,76 @@ mono_handle_soft_stack_ovf (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx,
        return FALSE;
 }
 
+typedef struct {
+       FILE *stream;
+       MonoMethod *omethod;
+       int count;
+} PrintOverflowUserData;
+
+static gboolean
+print_overflow_stack_frame (MonoMethod *method, gint32 native_offset, gint32 il_offset, gboolean managed, gpointer data)
+{
+       PrintOverflowUserData *user_data = data;
+       FILE *stream = user_data->stream;
+       gchar *location;
+
+       if (method) {
+               if (user_data->count == 0) {
+                       /* The first frame is in its prolog, so a line number cannot be computed */
+                       user_data->count ++;
+                       return FALSE;
+               }
+
+               /* If this is a one method overflow, skip the other instances */
+               if (method == user_data->omethod)
+                       return FALSE;
+
+               location = mono_debug_print_stack_frame (method, native_offset, mono_domain_get ());
+               fprintf (stream, "  %s\n", location);
+               g_free (location);
+
+               if (user_data->count == 1) {
+                       fprintf (stream, "  <...>\n");
+                       user_data->omethod = method;
+               } else {
+                       user_data->omethod = NULL;
+               }
+
+               user_data->count ++;
+       } else
+               fprintf (stream, "  at <unknown> <0x%05x>\n", native_offset);
+
+       return FALSE;
+}
+
+void
+mono_handle_hard_stack_ovf (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, guint8* fault_addr)
+{
+       PrintOverflowUserData ud;
+       MonoContext mctx;
+
+       /* we don't do much now, but we can warn the user with a useful message */
+       fprintf (stderr, "Stack overflow: IP: %p, fault addr: %p\n", mono_arch_ip_from_context (ctx), fault_addr);
+
+#ifdef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
+       mono_arch_sigctx_to_monoctx (ctx, &mctx);
+                       
+       fprintf (stderr, "Stacktrace:\n");
+
+       memset (&ud, 0, sizeof (ud));
+       ud.stream = stderr;
+
+       mono_jit_walk_stack_from_ctx (print_overflow_stack_frame, &mctx, MONO_UNWIND_LOOKUP_ACTUAL_METHOD, &ud);
+#else
+       if (ji && ji->method)
+               fprintf (stderr, "At %s\n", mono_method_full_name (ji->method, TRUE));
+       else
+               fprintf (stderr, "At <unmanaged>.\n");
+#endif
+
+       _exit (1);
+}
+
 static gboolean
 print_stack_frame (MonoMethod *method, gint32 native_offset, gint32 il_offset, gboolean managed, gpointer data)
 {