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;
}
}
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;
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)
// 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);
}
}
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)
{