X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fexception.c;h=6dedba6daaa391d92a8e04de9766cca36f6d59b0;hb=412f680e56f01d498d62f9fa6b3d3ef4fa29d5c3;hp=4d1db36939a5aa2c3e65d13d6180bce78d7f9196;hpb=cc9fa96a3163b4ac0b2df0726c72963017d802d6;p=mono.git diff --git a/mono/metadata/exception.c b/mono/metadata/exception.c index 4d1db36939a..6dedba6daaa 100644 --- a/mono/metadata/exception.c +++ b/mono/metadata/exception.c @@ -7,14 +7,21 @@ * Dick Porter (dick@ximian.com) * Miguel de Icaza (miguel@ximian.com) * - * (C) 2001, 2002 Ximian, Inc. + * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) + * Copyright 2004-2009 Novell, Inc (http://www.novell.com) */ #include #include +#include #include +#include #include +#ifdef HAVE_EXECINFO_H +#include +#endif + /** * mono_exception_from_name: * @image: the Mono image where to look for the class @@ -51,13 +58,18 @@ mono_exception_from_name_domain (MonoDomain *domain, MonoImage *image, { MonoClass *klass; MonoObject *o; + MonoDomain *caller_domain = mono_domain_get (); klass = mono_class_from_name (image, name_space, name); o = mono_object_new (domain, klass); g_assert (o != NULL); - + + if (domain != caller_domain) + mono_domain_set_internal (domain); mono_runtime_object_init (o); + if (domain != caller_domain) + mono_domain_set_internal (caller_domain); return (MonoException *)o; } @@ -75,10 +87,12 @@ mono_exception_from_name_domain (MonoDomain *domain, MonoImage *image, MonoException * mono_exception_from_token (MonoImage *image, guint32 token) { + MonoError error; MonoClass *klass; MonoObject *o; - klass = mono_class_get (image, token); + klass = mono_class_get_checked (image, token, &error); + g_assert (mono_error_ok (&error)); /* FIXME handle the error. */ o = mono_object_new (mono_domain_get (), klass); g_assert (o != NULL); @@ -185,7 +199,9 @@ MonoException * mono_exception_from_token_two_strings (MonoImage *image, guint32 token, MonoString *a1, MonoString *a2) { - MonoClass *klass = mono_class_get (image, token); + MonoError error; + MonoClass *klass = mono_class_get_checked (image, token, &error); + g_assert (mono_error_ok (&error)); /* FIXME handle the error. */ return create_exception_two_strings (klass, a1, a2); } @@ -562,14 +578,16 @@ mono_get_exception_type_initialization (const gchar *type_name, MonoException *i mono_class_init (klass); - /* TypeInitializationException only has 1 ctor with 2 args */ iter = NULL; while ((method = mono_class_get_methods (klass, &iter))) { - if (!strcmp (".ctor", mono_method_get_name (method)) && mono_method_signature (method)->param_count == 2) - break; + if (!strcmp (".ctor", mono_method_get_name (method))) { + MonoMethodSignature *sig = mono_method_signature (method); + + if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_STRING && mono_class_from_mono_type (sig->params [1]) == mono_defaults.exception_class) + break; + } method = NULL; } - g_assert (method); args [0] = mono_string_new (mono_domain_get (), type_name); @@ -585,7 +603,7 @@ mono_get_exception_type_initialization (const gchar *type_name, MonoException *i * mono_get_exception_synchronization_lock: * @inner: the inner exception. * - * Returns: a new instance of the System.TypeInitializationException + * Returns: a new instance of the System.SynchronizationLockException */ MonoException * mono_get_exception_synchronization_lock (const char *msg) @@ -666,6 +684,52 @@ mono_get_exception_out_of_memory (void) return mono_exception_from_name (mono_get_corlib (), "System", "OutOfMemoryException"); } +/** + * mono_get_exception_field_access: + * + * Returns: a new instance of the System.FieldAccessException + */ +MonoException * +mono_get_exception_field_access (void) +{ + return mono_exception_from_name (mono_get_corlib (), "System", "FieldAccessException"); +} + +/** + * mono_get_exception_field_access2: + * @msg: an informative message for the user. + * + * Returns: a new instance of the System.FieldAccessException + */ +MonoException * +mono_get_exception_field_access_msg (const char *msg) +{ + return mono_exception_from_name_msg (mono_get_corlib (), "System", "FieldAccessException", msg); +} + +/** + * mono_get_exception_method_access: + * + * Returns: a new instance of the System.MethodAccessException + */ +MonoException * +mono_get_exception_method_access (void) +{ + return mono_exception_from_name (mono_get_corlib (), "System", "MethodAccessException"); +} + +/** + * mono_get_exception_method_access2: + * @msg: an informative message for the user. + * + * Returns: a new instance of the System.MethodAccessException + */ +MonoException * +mono_get_exception_method_access_msg (const char *msg) +{ + return mono_exception_from_name_msg (mono_get_corlib (), "System", "MethodAccessException", msg); +} + /** * mono_get_exception_reflection_type_load: * @types: an array of types that were defined in the moduled loaded. @@ -680,12 +744,23 @@ mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions gpointer args [2]; MonoObject *exc; MonoMethod *method; + gpointer iter; klass = mono_class_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException"); g_assert (klass); mono_class_init (klass); - method = mono_class_get_method_from_name (klass, ".ctor", 2); + /* Find the Type[], Exception[] ctor */ + iter = NULL; + while ((method = mono_class_get_methods (klass, &iter))) { + if (!strcmp (".ctor", mono_method_get_name (method))) { + MonoMethodSignature *sig = mono_method_signature (method); + + if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_SZARRAY && sig->params [1]->type == MONO_TYPE_SZARRAY) + break; + } + method = NULL; + } g_assert (method); args [0] = types; @@ -696,3 +771,95 @@ mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions return (MonoException *) exc; } + +MonoException * +mono_get_exception_runtime_wrapped (MonoObject *wrapped_exception) +{ + MonoRuntimeWrappedException *ex = (MonoRuntimeWrappedException*) + mono_exception_from_name (mono_get_corlib (), "System.Runtime.CompilerServices", + "RuntimeWrappedException"); + + MONO_OBJECT_SETREF (ex, m_wrappedException, wrapped_exception); + return (MonoException*)ex; +} + +static gboolean +append_frame_and_continue (MonoMethod *method, gpointer ip, size_t native_offset, gboolean managed, gpointer user_data) +{ + MonoDomain *domain = mono_domain_get (); + GString *text = (GString*)user_data; + + if (method) { + char *msg = mono_debug_print_stack_frame (method, native_offset, domain); + g_string_append_printf (text, "%s\n", msg); + g_free (msg); + } else { + g_string_append_printf (text, "\n", ip); + } + + return FALSE; +} + +char * +mono_exception_get_managed_backtrace (MonoException *exc) +{ + GString *text; + + text = g_string_new_len (NULL, 20); + + if (!mono_get_eh_callbacks ()->mono_exception_walk_trace (exc, append_frame_and_continue, text)) + g_string_append (text, "managed backtrace not available\n"); + + return g_string_free (text, FALSE); +} + +char * +mono_exception_get_native_backtrace (MonoException *exc) +{ +#ifdef HAVE_BACKTRACE_SYMBOLS + MonoDomain *domain; + MonoArray *arr = exc->native_trace_ips; + int i, len; + GString *text; + char **messages; + + if (!arr) + return g_strdup (""); + domain = mono_domain_get (); + len = mono_array_length (arr); + text = g_string_new_len (NULL, len * 20); + messages = backtrace_symbols (mono_array_addr (arr, gpointer, 0), len); + + + for (i = 0; i < len; ++i) { + gpointer ip = mono_array_get (arr, gpointer, i); + MonoJitInfo *ji = mono_jit_info_table_find (mono_domain_get (), ip); + if (ji) { + char *msg = mono_debug_print_stack_frame (mono_jit_info_get_method (ji), (char*)ip - (char*)ji->code_start, domain); + g_string_append_printf (text, "%s\n", msg); + g_free (msg); + } else { + g_string_append_printf (text, "%s\n", messages [i]); + } + } + + free (messages); + return g_string_free (text, FALSE); +#else + return g_strdup (""); +#endif +} + +MonoString * +ves_icall_Mono_Runtime_GetNativeStackTrace (MonoException *exc) +{ + char *trace; + MonoString *res; + if (!exc) + mono_raise_exception (mono_get_exception_argument_null ("exception")); + + trace = mono_exception_get_native_backtrace (exc); + res = mono_string_new (mono_domain_get (), trace); + g_free (trace); + return res; +}