Merge pull request #3340 from lambdageek/dev/invoke-unhandled-exception-hook
authorAleksey Kliger (λgeek) <akliger@gmail.com>
Mon, 1 Aug 2016 23:22:43 +0000 (19:22 -0400)
committerGitHub <noreply@github.com>
Mon, 1 Aug 2016 23:22:43 +0000 (19:22 -0400)
[runtime] Move mono_invoke_unhandled_exception_hook to metadata

mono/metadata/exception.c
mono/metadata/exception.h
mono/metadata/threads.c
mono/mini/driver.c
mono/mini/mini-exceptions.c
mono/mini/mini-llvm.c
mono/mini/mini.h

index 2aff26dfd53788fe5080ef51e97cbaf0b9975045..e9ebcf38d384ca945bae7903c53e1658fee3691e 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <glib.h>
 #include <config.h>
+#include <mono/metadata/environment.h>
 #include <mono/metadata/exception.h>
 #include <mono/metadata/exception-internals.h>
 
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/mono-debug.h>
 #include <mono/utils/mono-error-internals.h>
+#include <mono/utils/mono-logger-internals.h>
 #include <string.h>
 
 #ifdef HAVE_EXECINFO_H
 #include <execinfo.h>
 #endif
 
+static MonoUnhandledExceptionFunc unhandled_exception_hook = NULL;
+static gpointer unhandled_exception_hook_data = NULL;
+
 /**
  * mono_exception_from_name:
  * @image: the Mono image where to look for the class
@@ -1051,3 +1056,50 @@ mono_error_set_pending_exception (MonoError *error)
        }
 }
 
+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 {
+               MonoError inner_error;
+               MonoObject *other = NULL;
+               MonoString *str = mono_object_try_to_string (exc, &other, &inner_error);
+               char *msg = NULL;
+               
+               if (str && is_ok (&inner_error)) {
+                       msg = mono_string_to_utf8_checked (str, &inner_error);
+               }
+               if (!is_ok (&inner_error)) {
+                       msg = g_strdup_printf ("Nested exception while formatting original exception");
+                       mono_error_cleanup (&inner_error);
+               } 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 ();
+}
index 3de5ae7ff57681981cf95a766105308ab2cacc79..895a67795fab27df7a2d7e7e1e98e100dbb6ad3c 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _MONO_METADATA_EXCEPTION_H_
 #define _MONO_METADATA_EXCEPTION_H_
 
+#include <glib.h>
 #include <mono/metadata/object.h>
 #include <mono/metadata/image.h>
 
@@ -147,6 +148,14 @@ MONO_RT_EXTERNAL_ONLY
 MONO_API MonoException *
 mono_get_exception_runtime_wrapped (MonoObject *wrapped_exception);
 
+/* Installs a function which is called when the runtime encounters an unhandled exception.
+ * This hook isn't expected to return.
+ * If no hook has been installed, the runtime will print a message before aborting.
+ */
+typedef void  (*MonoUnhandledExceptionFunc)         (MonoObject *exc, gpointer user_data);
+MONO_API void mono_install_unhandled_exception_hook (MonoUnhandledExceptionFunc func, gpointer user_data);
+void          mono_invoke_unhandled_exception_hook  (MonoObject *exc);
+
 MONO_END_DECLS
 
 #endif /* _MONO_METADATA_EXCEPTION_H_ */
index 523b5188cc5a5edb22fae1514edec68a6a49b79d..017a60f141c8ce4d17b441cf6513647b633638e9 100644 (file)
@@ -748,8 +748,11 @@ static guint32 WINAPI start_wrapper_internal(void *data)
 
                if (!mono_error_ok (&error)) {
                        MonoException *ex = mono_error_convert_to_exception (&error);
-                       if (ex)
+                       if (ex) {
                                mono_unhandled_exception (&ex->object);
+                               mono_invoke_unhandled_exception_hook (&ex->object);
+                               g_assert_not_reached ();
+                       }
                } else {
                        mono_error_cleanup (&error);
                }
@@ -5068,8 +5071,11 @@ mono_thread_internal_unhandled_exception (MonoObject* exc)
                        mono_thread_internal_reset_abort (mono_thread_internal_current ());
                } else if (!is_appdomainunloaded_exception (klass)) {
                        mono_unhandled_exception (exc);
-                       if (mono_environment_exitcode_get () == 1)
-                               exit (255);
+                       if (mono_environment_exitcode_get () == 1) {
+                               mono_environment_exitcode_set (255);
+                               mono_invoke_unhandled_exception_hook (exc);
+                               g_assert_not_reached ();
+                       }
                }
        }
 }
index aba82d5ffcb99b4112210194768ec78050379d33..9181e53b25257183de08774b3a793327ebe33be2 100644 (file)
@@ -1033,15 +1033,18 @@ mono_jit_exec (MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[
                if (exc) {
                        mono_unhandled_exception (exc);
                        mono_invoke_unhandled_exception_hook (exc);
-                       return 1;
+                       g_assert_not_reached ();
                }
                return res;
        } else {
                int res = mono_runtime_run_main_checked (method, argc, argv, &error);
                if (!is_ok (&error)) {
                        MonoException *ex = mono_error_convert_to_exception (&error);
-                       if (ex)
-                               mono_unhandled_exception ((MonoObject*)ex);
+                       if (ex) {
+                               mono_unhandled_exception (&ex->object);
+                               mono_invoke_unhandled_exception_hook (&ex->object);
+                               g_assert_not_reached ();
+                       }
                }
                return res;
        }
index 4030fb08384971855e3a7687813fb8ff7686e105..9c375a9aee767a3d055b8926db1cdf440d15f8ca 100644 (file)
@@ -89,9 +89,6 @@ 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);
@@ -2824,54 +2821,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 {
-               MonoError inner_error;
-               MonoObject *other = NULL;
-               MonoString *str = mono_object_try_to_string (exc, &other, &inner_error);
-               char *msg = NULL;
-               
-               if (str && is_ok (&inner_error)) {
-                       msg = mono_string_to_utf8_checked (str, &inner_error);
-               }
-               if (!is_ok (&inner_error)) {
-                       msg = g_strdup_printf ("Nested exception while formatting original exception");
-                       mono_error_cleanup (&inner_error);
-               } 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:
  *
index 6031df370c283e4be3816e4640b24b6528739bb4..61f3730f520383cefbc8fb9fc89b5d279f097cf4 100644 (file)
@@ -9034,7 +9034,8 @@ default_mono_llvm_unhandled_exception (void)
        MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
 
        mono_unhandled_exception (target);
-       exit (mono_environment_exitcode_get ());
+       mono_invoke_unhandled_exception_hook (target);
+       g_assert_not_reached ();
 }
 
 /*
index 21e8e62ad3793b8cd67db09a88a89d20f81c403a..bafaa414969ec65fa1aafd1bfbcaaa7da7307102 100644 (file)
@@ -2866,14 +2866,6 @@ MonoBoolean ves_icall_get_frame_info            (gint32 skip, MonoBoolean need_f
                                                 MonoString **file, gint32 *line, gint32 *column);
 void mono_set_cast_details                      (MonoClass *from, MonoClass *to);
 
-/* Installs a function which is called when the runtime encounters an unhandled exception.
- * This hook isn't expected to return.
- * If no hook has been installed, the runtime will print a message before aborting.
- */
-typedef void  (*MonoUnhandledExceptionFunc)         (MonoObject *exc, gpointer user_data);
-MONO_API void mono_install_unhandled_exception_hook (MonoUnhandledExceptionFunc func, gpointer user_data);
-void          mono_invoke_unhandled_exception_hook  (MonoObject *exc);
-
 void mono_decompose_typechecks (MonoCompile *cfg);
 /* Dominator/SSA methods */
 void        mono_compile_dominator_info         (MonoCompile *cfg, int dom_flags);