static gpointer try_more_restore_tramp = NULL;
static gpointer restore_stack_protection_tramp = NULL;
-static MonoUnhandledExceptionFunc unhandled_exception_hook = NULL;
-static gpointer unhandled_exception_hook_data = NULL;
-
static void try_more_restore (void);
static void restore_stack_protection (void);
static void mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoDomain *domain, MonoJitTlsData *jit_tls, MonoLMF *lmf, MonoUnwindOptions unwind_options, gpointer user_data);
gboolean
mono_exception_walk_trace (MonoException *ex, MonoExceptionFrameWalk func, gpointer user_data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
MonoArray *ta = ex->trace_ips;
int len, i;
if (dis_link) {
MonoObject *o = mono_gchandle_get_target (dis_link);
if (o) {
- list = mono_mlist_prepend (list, o);
+ list = mono_mlist_prepend_checked (list, o, &error);
+ mono_error_assert_ok (&error);
}
}
}
if (is_user_frame)
setup_stack_trace (mono_ex, dynamic_methods, initial_trace_ips, &trace_ips);
+#ifndef MONO_CROSS_COMPILE
#ifdef MONO_CONTEXT_SET_LLVM_EXC_REG
if (ji->from_llvm)
MONO_CONTEXT_SET_LLVM_EXC_REG (ctx, ex_obj);
/* store the exception object in bp + ei->exvar_offset */
*((gpointer *)(gpointer)((char *)MONO_CONTEXT_GET_BP (ctx) + ei->exvar_offset)) = ex_obj;
#endif
+#endif
#ifdef MONO_CONTEXT_SET_LLVM_EH_SELECTOR_REG
/*
}
}
+ MonoError isinst_error;
+ mono_error_init (&isinst_error);
if (ei->flags == MONO_EXCEPTION_CLAUSE_NONE && mono_object_isinst_checked (ex_obj, catch_class, &error)) {
setup_stack_trace (mono_ex, dynamic_methods, initial_trace_ips, &trace_ips);
g_slist_free (dynamic_methods);
MONO_CONTEXT_SET_IP (ctx, ei->handler_start);
return TRUE;
}
- mono_error_cleanup (&error);
+ mono_error_cleanup (&isinst_error);
}
}
mono_error_assert_ok (&error);
}
if (msg == NULL) {
- msg = message ? mono_string_to_utf8 ((MonoString *) message) : g_strdup ("(System.Exception.Message property not available)");
+ if (message) {
+ msg = mono_string_to_utf8_checked ((MonoString *) message, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error);
+ msg = g_strdup ("(error while display System.Exception.Message property)");
+ }
+ } else {
+ msg = g_strdup ("(System.Exception.Message property not available)");
+ }
}
g_print ("[%p:] EXCEPTION handling: %s.%s: %s\n", (void*)mono_native_thread_id_get (), mono_object_class (obj)->name_space, mono_object_class (obj)->name, msg);
g_free (msg);
ex_obj = obj;
if (((ei->flags == MONO_EXCEPTION_CLAUSE_NONE) || (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER))) {
+#ifndef MONO_CROSS_COMPILE
#ifdef MONO_CONTEXT_SET_LLVM_EXC_REG
MONO_CONTEXT_SET_LLVM_EXC_REG (ctx, ex_obj);
#else
g_assert (!ji->from_llvm);
/* store the exception object in bp + ei->exvar_offset */
*((gpointer *)(gpointer)((char *)MONO_CONTEXT_GET_BP (ctx) + ei->exvar_offset)) = ex_obj;
+#endif
#endif
}
gboolean
mono_handle_exception (MonoContext *ctx, MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
#ifndef DISABLE_PERFCOUNTERS
mono_perfcounters->exceptions_thrown++;
#endif
gpointer
mono_altstack_restore_prot (mgreg_t *regs, guint8 *code, gpointer *tramp_data, guint8* tramp)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
void (*func)(void) = (void (*)(void))tramp_data;
func ();
return NULL;
#endif
GString* text;
char *name;
-#ifndef HOST_WIN32
- char *wapi_desc;
-#endif
GError *error = NULL;
if (!thread)
else
g_string_append (text, "\n\"<unnamed thread>\"");
-#ifndef HOST_WIN32
- wapi_desc = wapi_current_thread_desc ();
- g_string_append_printf (text, " tid=0x%p this=0x%p %s\n", (gpointer)(gsize)thread->tid, thread, wapi_desc);
- free (wapi_desc);
-#endif
+ g_string_append_printf (text, " tid=0x%p this=0x%p ", (gpointer)(gsize)thread->tid, thread);
+ mono_thread_info_describe ((MonoThreadInfo*) thread->thread_info, text);
+ g_string_append (text, "\n");
#ifdef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
if (start_ctx) {
void
mono_resume_unwind (MonoContext *ctx)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id);
MonoContext new_ctx;
/*
* Finds the bottom handler block running and install a block guard if needed.
- * FIXME add full-aot support.
*/
gboolean
mono_install_handler_block_guard (MonoThreadUnwindState *ctx)
MonoJitTlsData *jit_tls = (MonoJitTlsData *)ctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS];
gpointer resume_ip;
- /* FIXME */
+#ifndef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD_AOT
if (mono_aot_only)
return FALSE;
+#endif
/* Guard against a null MonoJitTlsData. This can happens if the thread receives the
* interrupt signal before the JIT has time to initialize its TLS data for the given thread.
#endif
}
-void
-mono_install_unhandled_exception_hook (MonoUnhandledExceptionFunc func, gpointer user_data)
-{
- unhandled_exception_hook = func;
- unhandled_exception_hook_data = user_data;
-}
-
-void
-mono_invoke_unhandled_exception_hook (MonoObject *exc)
-{
- if (unhandled_exception_hook) {
- unhandled_exception_hook (exc, unhandled_exception_hook_data);
- } else {
- MonoObject *other = NULL;
- MonoString *str = mono_object_to_string (exc, &other);
- char *msg = NULL;
-
- if (str)
- msg = mono_string_to_utf8 (str);
- else if (other) {
- char *original_backtrace = mono_exception_get_managed_backtrace ((MonoException*)exc);
- char *nested_backtrace = mono_exception_get_managed_backtrace ((MonoException*)other);
-
- msg = g_strdup_printf ("Nested exception detected.\nOriginal Exception: %s\nNested exception:%s\n",
- original_backtrace, nested_backtrace);
-
- g_free (original_backtrace);
- g_free (nested_backtrace);
- } else {
- msg = g_strdup ("Nested exception trying to figure out what went wrong");
- }
- mono_runtime_printf_err ("[ERROR] FATAL UNHANDLED EXCEPTION: %s", msg);
- g_free (msg);
-#if defined(HOST_IOS)
- g_assertion_message ("Terminating runtime due to unhandled exception");
-#else
- exit (mono_environment_exitcode_get ());
-#endif
- }
-
- g_assert_not_reached ();
-}
-
/*
* mono_restore_context:
*
static void
throw_exception (MonoObject *ex, gboolean rethrow)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
MonoJitTlsData *jit_tls = mono_get_jit_tls ();
MonoException *mono_ex;
mono_error_assert_ok (&error);
mono_ex = mono_get_exception_runtime_wrapped_checked (ex, &error);
mono_error_assert_ok (&error);
+ jit_tls->thrown_non_exc = mono_gchandle_new (ex, FALSE);
}
else
mono_ex = (MonoException*)ex;
MonoObject *
mono_llvm_load_exception (void)
{
- MonoError error;
+ MonoError error;
MonoJitTlsData *jit_tls = mono_get_jit_tls ();
MonoException *mono_ex = (MonoException*)mono_gchandle_get_target (jit_tls->thrown_exc);
MonoJitTlsData *jit_tls = mono_get_jit_tls ();
mono_gchandle_free (jit_tls->thrown_exc);
jit_tls->thrown_exc = 0;
+ if (jit_tls->thrown_non_exc)
+ mono_gchandle_free (jit_tls->thrown_non_exc);
+ jit_tls->thrown_non_exc = 0;
mono_memory_barrier ();
}
gint32
mono_llvm_match_exception (MonoJitInfo *jinfo, guint32 region_start, guint32 region_end, gpointer rgctx, MonoObject *this_obj)
{
- MonoError error;
+ MonoError error;
MonoJitTlsData *jit_tls = mono_get_jit_tls ();
MonoObject *exc;
gint32 index = -1;
g_assert (jit_tls->thrown_exc);
exc = mono_gchandle_get_target (jit_tls->thrown_exc);
+ if (jit_tls->thrown_non_exc) {
+ /*
+ * Have to unwrap RuntimeWrappedExceptions if the
+ * method's assembly doesn't have a RuntimeCompatibilityAttribute.
+ */
+ if (!wrap_non_exception_throws (jinfo_get_method (jinfo)))
+ exc = mono_gchandle_get_target (jit_tls->thrown_non_exc);
+ }
+
for (int i = 0; i < jinfo->num_clauses; i++) {
MonoJitExceptionInfo *ei = &jinfo->clauses [i];
MonoClass *catch_class;
continue;
catch_class = ei->data.catch_class;
- if (catch_class->byval_arg.type == MONO_TYPE_VAR || catch_class->byval_arg.type == MONO_TYPE_MVAR || catch_class->byval_arg.type == MONO_TYPE_GENERICINST) {
+ if (mono_class_is_open_constructed_type (&catch_class->byval_arg)) {
MonoGenericContext context;
MonoType *inflated_type;