X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fexception.c;h=e9ebcf38d384ca945bae7903c53e1658fee3691e;hb=3c053143903c9927e7a31b4341f5a11f06cef69f;hp=e2e162f702a1efeb69e0226a5a4ab8eedb4d52d4;hpb=883a0ae745bf33b35d44bb730d5714936a2141f7;p=mono.git diff --git a/mono/metadata/exception.c b/mono/metadata/exception.c index e2e162f702a..e9ebcf38d38 100644 --- a/mono/metadata/exception.c +++ b/mono/metadata/exception.c @@ -13,6 +13,8 @@ */ #include +#include +#include #include #include @@ -21,12 +23,16 @@ #include #include #include +#include #include #ifdef HAVE_EXECINFO_H #include #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 @@ -173,15 +179,39 @@ mono_exception_from_name_two_strings (MonoImage *image, const char *name_space, const char *name, MonoString *a1, MonoString *a2) { MonoError error; - MonoClass *klass; MonoException *ret; - klass = mono_class_load_from_name (image, name_space, name); + ret = mono_exception_from_name_two_strings_checked (image, name_space, name, a1, a2, &error); + mono_error_cleanup (&error); + return ret; +} + +/** + * mono_exception_from_name_two_strings_checked: + * @image: the Mono image where to look for the class + * @name_space: the namespace for the class + * @name: class name + * @a1: first string argument to pass + * @a2: second string argument to pass + * @error: set on error + * + * Creates an exception from a constructor that takes two string + * arguments. + * + * Returns: the initialized exception instance. On failure returns + * NULL and sets @error. + */ +MonoException * +mono_exception_from_name_two_strings_checked (MonoImage *image, const char *name_space, + const char *name, MonoString *a1, MonoString *a2, + MonoError *error) +{ + MonoClass *klass; - ret = create_exception_two_strings (klass, a1, a2, &error); - mono_error_raise_exception (&error); /* FIXME don't raise here */ + mono_error_init (error); + klass = mono_class_load_from_name (image, name_space, name); - return ret; + return create_exception_two_strings (klass, a1, a2, error); } /** @@ -220,16 +250,31 @@ mono_exception_from_token_two_strings (MonoImage *image, guint32 token, MonoString *a1, MonoString *a2) { MonoError error; - MonoClass *klass; MonoException *ret; + ret = mono_exception_from_token_two_strings_checked (image, token, a1, a2, &error); + mono_error_cleanup (&error); + return ret; +} - klass = mono_class_get_checked (image, token, &error); - mono_error_assert_ok (&error); /* FIXME handle the error. */ +/** + * mono_exception_from_token_two_strings_checked: + * + * Same as mono_exception_from_name_two_strings, but lookup the exception class using + * IMAGE and TOKEN. + */ +MonoException * +mono_exception_from_token_two_strings_checked (MonoImage *image, guint32 token, + MonoString *a1, MonoString *a2, + MonoError *error) +{ + MonoClass *klass; - ret = create_exception_two_strings (klass, a1, a2, &error); - mono_error_raise_exception (&error); /* FIXME don't raise here */ + mono_error_init (error); - return ret; + klass = mono_class_get_checked (image, token, error); + mono_error_assert_ok (error); /* FIXME handle the error. */ + + return create_exception_two_strings (klass, a1, a2, error); } /** @@ -400,8 +445,11 @@ mono_get_exception_type_load (MonoString *class_name, char *assembly_name) { MonoString *s = assembly_name ? mono_string_new (mono_domain_get (), assembly_name) : mono_string_new (mono_domain_get (), ""); - return mono_exception_from_name_two_strings (mono_get_corlib (), "System", - "TypeLoadException", class_name, s); + MonoError error; + MonoException *ret = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System", + "TypeLoadException", class_name, s, &error); + mono_error_assert_ok (&error); + return ret; } /** @@ -441,8 +489,11 @@ mono_get_exception_missing_method (const char *class_name, const char *member_na MonoString *s1 = mono_string_new (mono_domain_get (), class_name); MonoString *s2 = mono_string_new (mono_domain_get (), member_name); - return mono_exception_from_name_two_strings (mono_get_corlib (), "System", - "MissingMethodException", s1, s2); + MonoError error; + MonoException *ret = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System", + "MissingMethodException", s1, s2, &error); + mono_error_assert_ok (&error); + return ret; } /** @@ -458,8 +509,11 @@ mono_get_exception_missing_field (const char *class_name, const char *member_nam MonoString *s1 = mono_string_new (mono_domain_get (), class_name); MonoString *s2 = mono_string_new (mono_domain_get (), member_name); - return mono_exception_from_name_two_strings (mono_get_corlib (), "System", - "MissingFieldException", s1, s2); + MonoError error; + MonoException *ret = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System", + "MissingFieldException", s1, s2, &error); + mono_error_assert_ok (&error); + return ret; } /** @@ -563,8 +617,11 @@ mono_get_exception_io (const char *msg) MonoException * mono_get_exception_file_not_found (MonoString *fname) { - return mono_exception_from_name_two_strings ( - mono_get_corlib (), "System.IO", "FileNotFoundException", fname, fname); + MonoError error; + MonoException *ret = mono_exception_from_name_two_strings_checked ( + mono_get_corlib (), "System.IO", "FileNotFoundException", fname, fname, &error); + mono_error_assert_ok (&error); + return ret; } /** @@ -579,8 +636,11 @@ mono_get_exception_file_not_found2 (const char *msg, MonoString *fname) { MonoString *s = msg ? mono_string_new (mono_domain_get (), msg) : NULL; - return mono_exception_from_name_two_strings ( - mono_get_corlib (), "System.IO", "FileNotFoundException", s, fname); + MonoError error; + MonoException *ret = mono_exception_from_name_two_strings_checked ( + mono_get_corlib (), "System.IO", "FileNotFoundException", s, fname, &error); + mono_error_assert_ok (&error); + return ret; } /** @@ -699,8 +759,11 @@ mono_get_exception_bad_image_format2 (const char *msg, MonoString *fname) { MonoString *s = msg ? mono_string_new (mono_domain_get (), msg) : NULL; - return mono_exception_from_name_two_strings ( - mono_get_corlib (), "System", "BadImageFormatException", s, fname); + MonoError error; + MonoException *ret = mono_exception_from_name_two_strings_checked ( + mono_get_corlib (), "System", "BadImageFormatException", s, fname, &error); + mono_error_assert_ok (&error); + return ret; } /** @@ -993,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 (); +}