[aot] Fix the linux bitcode build.
[mono.git] / mono / mini / mini-exceptions.c
index 60edcce554c91b89eeefd835771b4b2018599f69..fa24b73f186132b30eb3d4b358664d3f59e2d4f6 100644 (file)
@@ -89,14 +89,12 @@ static gpointer throw_corlib_exception_func;
 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);
 static void mono_raise_exception_with_ctx (MonoException *exc, MonoContext *ctx);
 static void mono_runtime_walk_stack_with_ctx (MonoJitStackWalk func, MonoContext *start_ctx, MonoUnwindOptions unwind_options, void *user_data);
+static gboolean mono_current_thread_has_handle_block_guard (void);
 
 void
 mono_exceptions_init (void)
@@ -139,6 +137,7 @@ mono_exceptions_init (void)
        cbs.mono_raise_exception_with_ctx = mono_raise_exception_with_ctx;
        cbs.mono_exception_walk_trace = mono_exception_walk_trace;
        cbs.mono_install_handler_block_guard = mono_install_handler_block_guard;
+       cbs.mono_current_thread_has_handle_block_guard = mono_current_thread_has_handle_block_guard;
        mono_install_eh_callbacks (&cbs);
 }
 
@@ -671,6 +670,8 @@ get_method_from_stack_frame (MonoJitInfo *ji, gpointer generic_info)
 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;
@@ -1697,7 +1698,15 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                                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);
@@ -2051,13 +2060,13 @@ mono_setup_altstack (MonoJitTlsData *tls)
 
        if (mono_mprotect (tls->stack_ovf_guard_base, tls->stack_ovf_guard_size, MONO_MMAP_NONE)) {
                /* mprotect can fail for the main thread stack */
-               gpointer gaddr = mono_valloc (tls->stack_ovf_guard_base, tls->stack_ovf_guard_size, MONO_MMAP_NONE|MONO_MMAP_PRIVATE|MONO_MMAP_ANON|MONO_MMAP_FIXED);
+               gpointer gaddr = mono_valloc (tls->stack_ovf_guard_base, tls->stack_ovf_guard_size, MONO_MMAP_NONE|MONO_MMAP_PRIVATE|MONO_MMAP_ANON|MONO_MMAP_FIXED, MONO_MEM_ACCOUNT_EXCEPTIONS);
                g_assert (gaddr == tls->stack_ovf_guard_base);
                tls->stack_ovf_valloced = TRUE;
        }
 
        /* Setup an alternate signal stack */
-       tls->signal_stack = mono_valloc (0, MONO_ARCH_SIGNAL_STACK_SIZE, MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_PRIVATE|MONO_MMAP_ANON);
+       tls->signal_stack = mono_valloc (0, MONO_ARCH_SIGNAL_STACK_SIZE, MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_PRIVATE|MONO_MMAP_ANON, MONO_MEM_ACCOUNT_EXCEPTIONS);
        tls->signal_stack_size = MONO_ARCH_SIGNAL_STACK_SIZE;
 
        g_assert (tls->signal_stack);
@@ -2083,9 +2092,9 @@ mono_free_altstack (MonoJitTlsData *tls)
        g_assert (err == 0);
 
        if (tls->signal_stack)
-               mono_vfree (tls->signal_stack, MONO_ARCH_SIGNAL_STACK_SIZE);
+               mono_vfree (tls->signal_stack, MONO_ARCH_SIGNAL_STACK_SIZE, MONO_MEM_ACCOUNT_EXCEPTIONS);
        if (tls->stack_ovf_valloced)
-               mono_vfree (tls->stack_ovf_guard_base, tls->stack_ovf_guard_size);
+               mono_vfree (tls->stack_ovf_guard_base, tls->stack_ovf_guard_size, MONO_MEM_ACCOUNT_EXCEPTIONS);
        else
                mono_mprotect (tls->stack_ovf_guard_base, tls->stack_ovf_guard_size, MONO_MMAP_READ|MONO_MMAP_WRITE);
 }
@@ -2380,7 +2389,7 @@ mono_handle_native_sigsegv (int signal, void *ctx, MONO_SIG_HANDLER_INFO_TYPE *i
        for (i =0; i < size; ++i) {
                mono_runtime_printf_err ("\t%s", names [i]);
        }
-       free (names);
+       g_free (names);
 
        /* Try to get more meaningful information using gdb */
 
@@ -2477,9 +2486,6 @@ mono_print_thread_dump_internal (void *sigctx, MonoContext *start_ctx)
 #endif
        GString* text;
        char *name;
-#ifndef HOST_WIN32
-       char *wapi_desc;
-#endif
        GError *error = NULL;
 
        if (!thread)
@@ -2497,11 +2503,9 @@ mono_print_thread_dump_internal (void *sigctx, MonoContext *start_ctx)
        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_internal_describe (thread, text);
+       g_string_append (text, "\n");
 
 #ifdef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
        if (start_ctx) {
@@ -2635,7 +2639,6 @@ install_handler_block_guard (MonoJitInfo *ji, MonoContext *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)
@@ -2644,9 +2647,10 @@ 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.
@@ -2674,6 +2678,13 @@ mono_install_handler_block_guard (MonoThreadUnwindState *ctx)
        return TRUE;
 }
 
+static gboolean
+mono_current_thread_has_handle_block_guard (void)
+{
+       MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id);
+       return jit_tls && jit_tls->handler_block_return_address != NULL;
+}
+
 #else
 gboolean
 mono_install_handler_block_guard (MonoThreadUnwindState *ctx)
@@ -2681,6 +2692,12 @@ mono_install_handler_block_guard (MonoThreadUnwindState *ctx)
        return FALSE;
 }
 
+static gboolean
+mono_current_thread_has_handle_block_guard (void)
+{
+       return FALSE;
+}
+
 #endif
 
 void
@@ -2814,49 +2831,6 @@ mono_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), gpoint
 #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:
  *
@@ -2905,6 +2879,8 @@ mono_jinfo_get_epilog_size (MonoJitInfo *ji)
 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;
@@ -2913,6 +2889,7 @@ throw_exception (MonoObject *ex, gboolean rethrow)
                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;
@@ -2992,7 +2969,7 @@ mono_llvm_resume_exception (void)
 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);
@@ -3044,6 +3021,9 @@ mono_llvm_clear_exception (void)
        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 ();
 }
@@ -3057,13 +3037,22 @@ mono_llvm_clear_exception (void)
 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;
@@ -3072,7 +3061,7 @@ mono_llvm_match_exception (MonoJitInfo *jinfo, guint32 region_start, guint32 reg
                        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;