#include <mono/metadata/mono-debug.h>
#include <mono/metadata/profiler.h>
#include <mono/metadata/mono-endian.h>
+#include <mono/metadata/environment.h>
#include <mono/utils/mono-mmap.h>
#include "mini.h"
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);
g_error ("This target doesn't support mono_arch_setup_async_callback");
#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);
+ if (str) {
+ char *msg = mono_string_to_utf8 (str);
+ fprintf (stderr, "[ERROR] FATAL UNHANDLED EXCEPTION: %s\n", msg);
+ fflush (stderr);
+ g_free (msg);
+ }
+
+ exit (mono_environment_exitcode_get ());
+ }
+
+ g_assert_not_reached ();
+}
(obj->vtable->klass == mono_defaults.threadabortexception_class)) {
mono_thread_exit ();
} else {
- MonoObject *other = NULL;
- MonoString *str = mono_object_to_string (obj, &other);
- if (str) {
- char *msg = mono_string_to_utf8 (str);
- fprintf (stderr, "[ERROR] FATAL UNHANDLED EXCEPTION: %s\n", msg);
- fflush (stderr);
- g_free (msg);
- }
-
- exit (mono_environment_exitcode_get ());
+ mono_invoke_unhandled_exception_hook (obj);
}
}
MonoString *ves_icall_System_Exception_get_trace (MonoException *exc) MONO_INTERNAL;
void mono_set_cast_details (MonoClass *from, MonoClass *to) MONO_INTERNAL;
+/* 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);
+void mono_install_unhandled_exception_hook (MonoUnhandledExceptionFunc func, gpointer user_data);
+void mono_invoke_unhandled_exception_hook (MonoObject *exc);
+
/* Dominator/SSA methods */
void mono_compile_dominator_info (MonoCompile *cfg, int dom_flags) MONO_INTERNAL;
void mono_compute_natural_loops (MonoCompile *cfg) MONO_INTERNAL;