X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmono-error.c;h=7e186b6b717ce06b2f4103bb2ab3abe22e5ce2df;hb=68be3904cf770be9f98a6ce0e8d71899cb94f189;hp=84d04781e708927500ec5fc106ec46066cacfda4;hpb=d1c2c7172df75be26e219e018b22de6104b77079;p=mono.git diff --git a/mono/utils/mono-error.c b/mono/utils/mono-error.c index 84d04781e70..7e186b6b717 100644 --- a/mono/utils/mono-error.c +++ b/mono/utils/mono-error.c @@ -8,10 +8,12 @@ */ #include +#include #include "mono-error.h" #include "mono-error-internals.h" #include +#include #include #include @@ -39,6 +41,8 @@ is_managed_exception (MonoErrorInternal *error) static void mono_error_prepare (MonoErrorInternal *error) { + /* mono_error_set_* after a mono_error_cleanup without an intervening init */ + g_assert (error->error_code != MONO_ERROR_CLEANUP_CALLED_SENTINEL); if (error->error_code != MONO_ERROR_NONE) return; @@ -106,15 +110,30 @@ void mono_error_cleanup (MonoError *oerror) { MonoErrorInternal *error = (MonoErrorInternal*)oerror; - if (error->error_code == MONO_ERROR_NONE) + short int orig_error_code = error->error_code; + gboolean free_strings = error->flags & MONO_ERROR_FREE_STRINGS; + gboolean has_instance_handle = is_managed_exception (error); + + /* Two cleanups in a row without an intervening init. */ + g_assert (orig_error_code != MONO_ERROR_CLEANUP_CALLED_SENTINEL); + + /* Mark it as cleaned up. */ + error->error_code = MONO_ERROR_CLEANUP_CALLED_SENTINEL; + error->flags = 0; + + if (orig_error_code == MONO_ERROR_NONE) return; - if (is_managed_exception (error)) + + if (has_instance_handle) mono_gchandle_free (error->exn.instance_handle); + g_free ((char*)error->full_message); g_free ((char*)error->full_message_with_fields); - if (!(error->flags & MONO_ERROR_FREE_STRINGS)) //no memory was allocated + error->full_message = NULL; + error->full_message_with_fields = NULL; + if (!free_strings) //no memory was allocated return; g_free ((char*)error->type_name); @@ -123,6 +142,9 @@ mono_error_cleanup (MonoError *oerror) g_free ((char*)error->exception_name_space); g_free ((char*)error->exception_name); g_free ((char*)error->first_argument); + error->type_name = error->assembly_name = error->member_name = error->exception_name_space = error->exception_name = error->first_argument = NULL; + error->exn.klass = NULL; + } gboolean @@ -420,6 +442,17 @@ mono_error_set_invalid_operation (MonoError *oerror, const char *msg_format, ... va_end (args); } +void +mono_error_set_invalid_program (MonoError *oerror, const char *msg_format, ...) +{ + MonoErrorInternal *error = (MonoErrorInternal*)oerror; + + mono_error_prepare (error); + error->error_code = MONO_ERROR_INVALID_PROGRAM; + + set_error_message (); +} + void mono_error_set_exception_instance (MonoError *oerror, MonoException *exc) { @@ -542,7 +575,7 @@ mono_error_prepare_exception (MonoError *oerror, MonoError *error_out) break; } - exception = mono_exception_from_name_two_strings (mono_defaults.corlib, "System", "MissingMethodException", type_name, method_name); + exception = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "MissingMethodException", type_name, method_name, error_out); if (exception) set_message_on_exception (exception, error, error_out); } else { @@ -562,7 +595,7 @@ mono_error_prepare_exception (MonoError *oerror, MonoError *error_out) break; } - exception = mono_exception_from_name_two_strings (mono_defaults.corlib, "System", "MissingFieldException", type_name, field_name); + exception = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "MissingFieldException", type_name, field_name, error_out); if (exception) set_message_on_exception (exception, error, error_out); } else { @@ -584,7 +617,7 @@ mono_error_prepare_exception (MonoError *oerror, MonoError *error_out) } } - exception = mono_exception_from_name_two_strings (mono_get_corlib (), "System", "TypeLoadException", type_name, assembly_name); + exception = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System", "TypeLoadException", type_name, assembly_name, error_out); if (exception) set_message_on_exception (exception, error, error_out); } else { @@ -610,9 +643,9 @@ mono_error_prepare_exception (MonoError *oerror, MonoError *error_out) } if (error->error_code == MONO_ERROR_FILE_NOT_FOUND) - exception = mono_exception_from_name_two_strings (mono_get_corlib (), "System.IO", "FileNotFoundException", msg, assembly_name); + exception = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System.IO", "FileNotFoundException", msg, assembly_name, error_out); else - exception = mono_exception_from_name_two_strings (mono_defaults.corlib, "System", "BadImageFormatException", msg, assembly_name); + exception = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "BadImageFormatException", msg, assembly_name, error_out); } else { if (error->error_code == MONO_ERROR_FILE_NOT_FOUND) exception = mono_exception_from_name_msg (mono_get_corlib (), "System.IO", "FileNotFoundException", error->full_message); @@ -664,6 +697,17 @@ mono_error_prepare_exception (MonoError *oerror, MonoError *error_out) exception = (MonoException*) mono_gchandle_get_target (error->exn.instance_handle); break; + case MONO_ERROR_CLEANUP_CALLED_SENTINEL: + mono_error_set_execution_engine (error_out, "MonoError reused after mono_error_cleanup"); + break; + + case MONO_ERROR_INVALID_PROGRAM: { + gboolean lacks_message = error->flags & MONO_ERROR_INCOMPLETE; + if (lacks_message) + return mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", ""); + else + return mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", error->full_message); + } default: mono_error_set_execution_engine (error_out, "Invalid error-code %d", error->error_code); }