2 * exception.c: Exception handling
5 * Paolo Molaro (lupus@ximian.com)
6 * Dietmar Maurer (dietmar@ximian.com)
7 * Dick Porter (dick@ximian.com)
8 * Miguel de Icaza (miguel@ximian.com)
10 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
11 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
12 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
17 #include <mono/metadata/environment.h>
18 #include <mono/metadata/exception.h>
19 #include <mono/metadata/exception-internals.h>
21 #include <mono/metadata/object-internals.h>
22 #include <mono/metadata/metadata-internals.h>
23 #include <mono/metadata/appdomain.h>
24 #include <mono/metadata/mono-debug.h>
25 #include <mono/utils/mono-error-internals.h>
26 #include <mono/utils/mono-logger-internals.h>
29 #ifdef HAVE_EXECINFO_H
33 static MonoUnhandledExceptionFunc unhandled_exception_hook = NULL;
34 static gpointer unhandled_exception_hook_data = NULL;
37 * mono_exception_from_name:
38 * @image: the Mono image where to look for the class
39 * @name_space: the namespace for the class
42 * Creates an exception of the given namespace/name class in the
45 * Returns: the initialized exception instance.
48 mono_exception_from_name (MonoImage *image, const char *name_space,
51 return mono_exception_from_name_domain (mono_domain_get (), image, name_space, name);
55 * mono_exception_from_name_domain:
56 * @domain: Domain where the return object will be created.
57 * @image: the Mono image where to look for the class
58 * @name_space: the namespace for the class
61 * Creates an exception object of the given namespace/name class on
64 * Returns: the initialized exception instance.
67 mono_exception_from_name_domain (MonoDomain *domain, MonoImage *image,
68 const char* name_space, const char *name)
73 MonoDomain *caller_domain = mono_domain_get ();
75 klass = mono_class_load_from_name (image, name_space, name);
77 o = mono_object_new_checked (domain, klass, &error);
78 mono_error_assert_ok (&error);
80 if (domain != caller_domain)
81 mono_domain_set_internal (domain);
82 mono_runtime_object_init_checked (o, &error);
83 mono_error_assert_ok (&error);
85 if (domain != caller_domain)
86 mono_domain_set_internal (caller_domain);
88 return (MonoException *)o;
93 * mono_exception_from_token:
94 * @image: the Mono image where to look for the class
95 * @token: The type token of the class
97 * Creates an exception of the type given by @token.
99 * Returns: the initialized exception instance.
102 mono_exception_from_token (MonoImage *image, guint32 token)
108 klass = mono_class_get_checked (image, token, &error);
109 mono_error_assert_ok (&error);
111 o = mono_object_new_checked (mono_domain_get (), klass, &error);
112 mono_error_assert_ok (&error);
114 mono_runtime_object_init_checked (o, &error);
115 mono_error_assert_ok (&error);
117 return (MonoException *)o;
120 static MonoException *
121 create_exception_two_strings (MonoClass *klass, MonoString *a1, MonoString *a2, MonoError *error)
123 MonoDomain *domain = mono_domain_get ();
124 MonoMethod *method = NULL;
134 o = mono_object_new_checked (domain, klass, error);
135 mono_error_assert_ok (error);
138 while ((m = mono_class_get_methods (klass, &iter))) {
139 MonoMethodSignature *sig;
141 if (strcmp (".ctor", mono_method_get_name (m)))
143 sig = mono_method_signature (m);
144 if (sig->param_count != count)
147 if (sig->params [0]->type != MONO_TYPE_STRING)
149 if (count == 2 && sig->params [1]->type != MONO_TYPE_STRING)
158 mono_runtime_invoke_checked (method, o, args, error);
159 return_val_if_nok (error, NULL);
161 return (MonoException *) o;
165 * mono_exception_from_name_two_strings:
166 * @image: the Mono image where to look for the class
167 * @name_space: the namespace for the class
169 * @a1: first string argument to pass
170 * @a2: second string argument to pass
172 * Creates an exception from a constructor that takes two string
175 * Returns: the initialized exception instance.
178 mono_exception_from_name_two_strings (MonoImage *image, const char *name_space,
179 const char *name, MonoString *a1, MonoString *a2)
184 ret = mono_exception_from_name_two_strings_checked (image, name_space, name, a1, a2, &error);
185 mono_error_cleanup (&error);
190 * mono_exception_from_name_two_strings_checked:
191 * @image: the Mono image where to look for the class
192 * @name_space: the namespace for the class
194 * @a1: first string argument to pass
195 * @a2: second string argument to pass
196 * @error: set on error
198 * Creates an exception from a constructor that takes two string
201 * Returns: the initialized exception instance. On failure returns
202 * NULL and sets @error.
205 mono_exception_from_name_two_strings_checked (MonoImage *image, const char *name_space,
206 const char *name, MonoString *a1, MonoString *a2,
211 mono_error_init (error);
212 klass = mono_class_load_from_name (image, name_space, name);
214 return create_exception_two_strings (klass, a1, a2, error);
218 * mono_exception_from_name_msg:
219 * @image: the Mono image where to look for the class
220 * @name_space: the namespace for the class
222 * @msg: the message to embed inside the exception
224 * Creates an exception and initializes its message field.
226 * Returns: the initialized exception instance.
229 mono_exception_from_name_msg (MonoImage *image, const char *name_space,
230 const char *name, const char *msg)
234 ex = mono_exception_from_name (image, name_space, name);
237 MONO_OBJECT_SETREF (ex, message, mono_string_new (mono_object_get_domain ((MonoObject*)ex), msg));
243 * mono_exception_from_token_two_strings:
245 * Same as mono_exception_from_name_two_strings, but lookup the exception class using
249 mono_exception_from_token_two_strings (MonoImage *image, guint32 token,
250 MonoString *a1, MonoString *a2)
254 ret = mono_exception_from_token_two_strings_checked (image, token, a1, a2, &error);
255 mono_error_cleanup (&error);
260 * mono_exception_from_token_two_strings_checked:
262 * Same as mono_exception_from_name_two_strings, but lookup the exception class using
266 mono_exception_from_token_two_strings_checked (MonoImage *image, guint32 token,
267 MonoString *a1, MonoString *a2,
272 mono_error_init (error);
274 klass = mono_class_get_checked (image, token, error);
275 mono_error_assert_ok (error); /* FIXME handle the error. */
277 return create_exception_two_strings (klass, a1, a2, error);
281 * mono_get_exception_divide_by_zero:
283 * Returns: a new instance of the `System.DivideByZeroException`
286 mono_get_exception_divide_by_zero ()
288 return mono_exception_from_name (mono_get_corlib (), "System",
289 "DivideByZeroException");
293 * mono_get_exception_security:
295 * Returns: a new instance of the `System.Security.SecurityException`
298 mono_get_exception_security ()
300 return mono_exception_from_name (mono_get_corlib (), "System.Security",
301 "SecurityException");
305 * mono_get_exception_thread_abort:
307 * Returns: a new instance of the `System.Threading.ThreadAbortException`
310 mono_get_exception_thread_abort ()
312 return mono_exception_from_name (mono_get_corlib (), "System.Threading",
313 "ThreadAbortException");
317 * mono_get_exception_thread_interrupted:
319 * Returns: a new instance of the `System.Threading.ThreadInterruptedException`
322 mono_get_exception_thread_interrupted ()
324 return mono_exception_from_name (mono_get_corlib (), "System.Threading",
325 "ThreadInterruptedException");
329 * mono_get_exception_arithmetic:
331 * Returns: a new instance of the `System.ArithmeticException`
334 mono_get_exception_arithmetic ()
336 return mono_exception_from_name (mono_get_corlib (), "System",
337 "ArithmeticException");
341 * mono_get_exception_overflow:
343 * Returns: a new instance of the `System.OverflowException`
346 mono_get_exception_overflow ()
348 return mono_exception_from_name (mono_get_corlib (), "System",
349 "OverflowException");
353 * mono_get_exception_null_reference:
355 * Returns: a new instance of the `System.NullReferenceException`
358 mono_get_exception_null_reference ()
360 return mono_exception_from_name (mono_get_corlib (), "System",
361 "NullReferenceException");
365 * mono_get_exception_execution_engine:
366 * @msg: the message to pass to the user
368 * Returns: a new instance of the `System.ExecutionEngineException`
371 mono_get_exception_execution_engine (const char *msg)
373 return mono_exception_from_name_msg (mono_get_corlib (), "System", "ExecutionEngineException", msg);
377 * mono_get_exception_serialization:
378 * @msg: the message to pass to the user
380 * Returns: a new instance of the `System.Runtime.Serialization.SerializationException`
383 mono_get_exception_serialization (const char *msg)
385 return mono_exception_from_name_msg (mono_get_corlib (), "System.Runtime.Serialization", "SerializationException", msg);
389 * mono_get_exception_invalid_cast:
391 * Returns: a new instance of the `System.InvalidCastException`
394 mono_get_exception_invalid_cast ()
396 return mono_exception_from_name (mono_get_corlib (), "System", "InvalidCastException");
400 * mono_get_exception_invalid_operation:
401 * @msg: the message to pass to the user
403 * Returns: a new instance of the `System.InvalidOperationException`
406 mono_get_exception_invalid_operation (const char *msg)
408 return mono_exception_from_name_msg (mono_get_corlib (), "System",
409 "InvalidOperationException", msg);
413 * mono_get_exception_index_out_of_range:
415 * Returns: a new instance of the `System.IndexOutOfRangeException`
418 mono_get_exception_index_out_of_range ()
420 return mono_exception_from_name (mono_get_corlib (), "System",
421 "IndexOutOfRangeException");
425 * mono_get_exception_array_type_mismatch:
427 * Returns: a new instance of the `System.ArrayTypeMismatchException`
430 mono_get_exception_array_type_mismatch ()
432 return mono_exception_from_name (mono_get_corlib (), "System",
433 "ArrayTypeMismatchException");
437 * mono_get_exception_type_load:
438 * @class_name: the name of the class that could not be loaded
439 * @assembly_name: the assembly where the class was looked up.
441 * Returns: a new instance of the `System.TypeLoadException`
444 mono_get_exception_type_load (MonoString *class_name, char *assembly_name)
446 MonoString *s = assembly_name ? mono_string_new (mono_domain_get (), assembly_name) : mono_string_new (mono_domain_get (), "");
449 MonoException *ret = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System",
450 "TypeLoadException", class_name, s, &error);
451 mono_error_assert_ok (&error);
456 * mono_get_exception_not_implemented:
457 * @msg: the message to pass to the user
459 * Returns: a new instance of the `System.NotImplementedException`
462 mono_get_exception_not_implemented (const char *msg)
464 return mono_exception_from_name_msg (mono_get_corlib (), "System", "NotImplementedException", msg);
468 * mono_get_exception_not_supported:
469 * @msg: the message to pass to the user
471 * Returns: a new instance of the `System.NotSupportedException`
474 mono_get_exception_not_supported (const char *msg)
476 return mono_exception_from_name_msg (mono_get_corlib (), "System", "NotSupportedException", msg);
480 * mono_get_exception_missing_method:
481 * @class_name: the class where the lookup was performed.
482 * @member_name: the name of the missing method.
484 * Returns: a new instance of the `System.MissingMethodException`
487 mono_get_exception_missing_method (const char *class_name, const char *member_name)
489 MonoString *s1 = mono_string_new (mono_domain_get (), class_name);
490 MonoString *s2 = mono_string_new (mono_domain_get (), member_name);
493 MonoException *ret = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System",
494 "MissingMethodException", s1, s2, &error);
495 mono_error_assert_ok (&error);
500 * mono_get_exception_missing_field:
501 * @class_name: the class where the lookup was performed
502 * @member_name: the name of the missing method.
504 * Returns: a new instance of the `System.MissingFieldException`
507 mono_get_exception_missing_field (const char *class_name, const char *member_name)
509 MonoString *s1 = mono_string_new (mono_domain_get (), class_name);
510 MonoString *s2 = mono_string_new (mono_domain_get (), member_name);
513 MonoException *ret = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System",
514 "MissingFieldException", s1, s2, &error);
515 mono_error_assert_ok (&error);
520 * mono_get_exception_argument_null:
521 * @arg: the name of the argument that is null
523 * Returns: a new instance of the `System.ArgumentNullException`
526 mono_get_exception_argument_null (const char *arg)
530 ex = mono_exception_from_name (
531 mono_get_corlib (), "System", "ArgumentNullException");
534 MonoArgumentException *argex = (MonoArgumentException *)ex;
535 MONO_OBJECT_SETREF (argex, param_name, mono_string_new (mono_object_get_domain ((MonoObject*)ex), arg));
542 * mono_get_exception_argument:
543 * @arg: the name of the invalid argument.
545 * Returns: a new instance of the `System.ArgumentException`
548 mono_get_exception_argument (const char *arg, const char *msg)
552 ex = mono_exception_from_name_msg (
553 mono_get_corlib (), "System", "ArgumentException", msg);
556 MonoArgumentException *argex = (MonoArgumentException *)ex;
557 MONO_OBJECT_SETREF (argex, param_name, mono_string_new (mono_object_get_domain ((MonoObject*)ex), arg));
564 * mono_get_exception_argument_out_of_range:
565 * @arg: the name of the out of range argument.
567 * Returns: a new instance of the `System.ArgumentOutOfRangeException`
570 mono_get_exception_argument_out_of_range (const char *arg)
574 ex = mono_exception_from_name (
575 mono_get_corlib (), "System", "ArgumentOutOfRangeException");
578 MonoArgumentException *argex = (MonoArgumentException *)ex;
579 MONO_OBJECT_SETREF (argex, param_name, mono_string_new (mono_object_get_domain ((MonoObject*)ex), arg));
586 * mono_get_exception_thread_state:
587 * @msg: the message to present to the user
589 * Returns: a new instance of the `System.Threading.ThreadStateException`
592 mono_get_exception_thread_state (const char *msg)
594 return mono_exception_from_name_msg (
595 mono_get_corlib (), "System.Threading", "ThreadStateException", msg);
599 * mono_get_exception_io:
600 * @msg: the message to present to the user
602 * Returns: a new instance of the `System.IO.IOException`
605 mono_get_exception_io (const char *msg)
607 return mono_exception_from_name_msg (
608 mono_get_corlib (), "System.IO", "IOException", msg);
612 * mono_get_exception_file_not_found:
613 * @fname: the name of the file not found.
615 * Returns: a new instance of the `System.IO.FileNotFoundException`
618 mono_get_exception_file_not_found (MonoString *fname)
621 MonoException *ret = mono_exception_from_name_two_strings_checked (
622 mono_get_corlib (), "System.IO", "FileNotFoundException", fname, fname, &error);
623 mono_error_assert_ok (&error);
628 * mono_get_exception_file_not_found2:
629 * @msg: an informative message for the user.
630 * @fname: the name of the file not found.
632 * Returns: a new instance of the `System.IO.FileNotFoundException`
635 mono_get_exception_file_not_found2 (const char *msg, MonoString *fname)
637 MonoString *s = msg ? mono_string_new (mono_domain_get (), msg) : NULL;
640 MonoException *ret = mono_exception_from_name_two_strings_checked (
641 mono_get_corlib (), "System.IO", "FileNotFoundException", s, fname, &error);
642 mono_error_assert_ok (&error);
647 * mono_get_exception_type_initialization:
648 * @type_name: the name of the type that failed to initialize.
649 * @inner: the inner exception.
651 * Returns: a new instance of the `System.TypeInitializationException`
654 mono_get_exception_type_initialization (const gchar *type_name, MonoException *inner)
657 MonoException *ret = mono_get_exception_type_initialization_checked (type_name, inner, &error);
658 if (!is_ok (&error)) {
659 mono_error_cleanup (&error);
667 mono_get_exception_type_initialization_checked (const gchar *type_name, MonoException *inner, MonoError *error)
675 klass = mono_class_load_from_name (mono_get_corlib (), "System", "TypeInitializationException");
677 mono_class_init (klass);
680 while ((method = mono_class_get_methods (klass, &iter))) {
681 if (!strcmp (".ctor", mono_method_get_name (method))) {
682 MonoMethodSignature *sig = mono_method_signature (method);
684 if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_STRING && mono_class_from_mono_type (sig->params [1]) == mono_defaults.exception_class)
691 args [0] = mono_string_new (mono_domain_get (), type_name);
694 exc = mono_object_new_checked (mono_domain_get (), klass, error);
695 mono_error_assert_ok (error);
697 mono_runtime_invoke_checked (method, exc, args, error);
698 return_val_if_nok (error, NULL);
700 return (MonoException *) exc;
704 * mono_get_exception_synchronization_lock:
705 * @inner: the inner exception.
707 * Returns: a new instance of the `System.SynchronizationLockException`
710 mono_get_exception_synchronization_lock (const char *msg)
712 return mono_exception_from_name_msg (mono_get_corlib (), "System.Threading", "SynchronizationLockException", msg);
716 * mono_get_exception_cannot_unload_appdomain:
717 * @inner: the inner exception.
719 * Returns: a new instance of the `System.CannotUnloadAppDomainException`
722 mono_get_exception_cannot_unload_appdomain (const char *msg)
724 return mono_exception_from_name_msg (mono_get_corlib (), "System", "CannotUnloadAppDomainException", msg);
728 * mono_get_exception_appdomain_unloaded
730 * Returns: a new instance of the `System.AppDomainUnloadedException`
733 mono_get_exception_appdomain_unloaded (void)
735 return mono_exception_from_name (mono_get_corlib (), "System", "AppDomainUnloadedException");
739 * mono_get_exception_bad_image_format:
740 * @msg: an informative message for the user.
742 * Returns: a new instance of the `System.BadImageFormatException`
745 mono_get_exception_bad_image_format (const char *msg)
747 return mono_exception_from_name_msg (mono_get_corlib (), "System", "BadImageFormatException", msg);
751 * mono_get_exception_bad_image_format2:
752 * @msg: an informative message for the user.
753 * @fname: The full name of the file with the invalid image.
755 * Returns: a new instance of the `System.BadImageFormatException`
758 mono_get_exception_bad_image_format2 (const char *msg, MonoString *fname)
760 MonoString *s = msg ? mono_string_new (mono_domain_get (), msg) : NULL;
763 MonoException *ret = mono_exception_from_name_two_strings_checked (
764 mono_get_corlib (), "System", "BadImageFormatException", s, fname, &error);
765 mono_error_assert_ok (&error);
770 * mono_get_exception_stack_overflow:
772 * Returns: a new instance of the `System.StackOverflowException`
775 mono_get_exception_stack_overflow (void)
777 return mono_exception_from_name (mono_get_corlib (), "System", "StackOverflowException");
781 * mono_get_exception_out_of_memory:
783 * Returns: a new instance of the `System.OutOfMemoryException`
786 mono_get_exception_out_of_memory (void)
788 return mono_exception_from_name (mono_get_corlib (), "System", "OutOfMemoryException");
792 * mono_get_exception_field_access:
794 * Returns: a new instance of the `System.FieldAccessException`
797 mono_get_exception_field_access (void)
799 return mono_exception_from_name (mono_get_corlib (), "System", "FieldAccessException");
803 * mono_get_exception_field_access2:
804 * @msg: an informative message for the user.
806 * Returns: a new instance of the `System.FieldAccessException`
809 mono_get_exception_field_access_msg (const char *msg)
811 return mono_exception_from_name_msg (mono_get_corlib (), "System", "FieldAccessException", msg);
815 * mono_get_exception_method_access:
817 * Returns: a new instance of the `System.MethodAccessException`
820 mono_get_exception_method_access (void)
822 return mono_exception_from_name (mono_get_corlib (), "System", "MethodAccessException");
826 * mono_get_exception_method_access2:
827 * @msg: an informative message for the user.
829 * Returns: a new instance of the `System.MethodAccessException`
832 mono_get_exception_method_access_msg (const char *msg)
834 return mono_exception_from_name_msg (mono_get_corlib (), "System", "MethodAccessException", msg);
838 * mono_get_exception_reflection_type_load:
839 * @types: an array of types that were defined in the moduled loaded.
840 * @exceptions: an array of exceptions that were thrown during the type loading.
842 * Returns: a new instance of the `System.Reflection.ReflectionTypeLoadException`
845 mono_get_exception_reflection_type_load (MonoArray *types_raw, MonoArray *exceptions_raw)
847 HANDLE_FUNCTION_ENTER ();
849 MONO_HANDLE_DCL (MonoArray, types);
850 MONO_HANDLE_DCL (MonoArray, exceptions);
851 MonoExceptionHandle ret = mono_get_exception_reflection_type_load_checked (types, exceptions, &error);
852 if (is_ok (&error)) {
853 mono_error_cleanup (&error);
854 ret = MONO_HANDLE_CAST (MonoException, NULL_HANDLE);
859 HANDLE_FUNCTION_RETURN_OBJ (ret);
864 mono_get_exception_reflection_type_load_checked (MonoArrayHandle types, MonoArrayHandle exceptions, MonoError *error)
870 mono_error_init (error);
872 klass = mono_class_load_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException");
874 mono_class_init (klass);
876 /* Find the Type[], Exception[] ctor */
878 while ((method = mono_class_get_methods (klass, &iter))) {
879 if (!strcmp (".ctor", mono_method_get_name (method))) {
880 MonoMethodSignature *sig = mono_method_signature (method);
882 if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_SZARRAY && sig->params [1]->type == MONO_TYPE_SZARRAY)
889 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_object_new_checked (mono_domain_get (), klass, error));
890 mono_error_assert_ok (error);
893 args [0] = MONO_HANDLE_RAW (types);
894 args [1] = MONO_HANDLE_RAW (exceptions);
896 mono_runtime_invoke_checked (method, MONO_HANDLE_RAW (exc), args, error);
897 return_val_if_nok (error, MONO_HANDLE_CAST (MonoException, NULL_HANDLE));
903 mono_get_exception_runtime_wrapped (MonoObject *wrapped_exception)
906 MonoException *ret = mono_get_exception_runtime_wrapped_checked (wrapped_exception, &error);
907 if (!is_ok (&error)) {
908 mono_error_cleanup (&error);
916 mono_get_exception_runtime_wrapped_checked (MonoObject *wrapped_exception, MonoError *error)
921 MonoDomain *domain = mono_domain_get ();
922 gpointer params [16];
924 klass = mono_class_load_from_name (mono_get_corlib (), "System.Runtime.CompilerServices", "RuntimeWrappedException");
926 o = mono_object_new_checked (domain, klass, error);
927 mono_error_assert_ok (error);
928 g_assert (o != NULL);
930 method = mono_class_get_method_from_name (klass, ".ctor", 1);
933 params [0] = wrapped_exception;
935 mono_runtime_invoke_checked (method, o, params, error);
936 return_val_if_nok (error, NULL);
938 return (MonoException *)o;
942 append_frame_and_continue (MonoMethod *method, gpointer ip, size_t native_offset, gboolean managed, gpointer user_data)
944 MonoDomain *domain = mono_domain_get ();
945 GString *text = (GString*)user_data;
948 char *msg = mono_debug_print_stack_frame (method, native_offset, domain);
949 g_string_append_printf (text, "%s\n", msg);
952 g_string_append_printf (text, "<unknown native frame 0x%x>\n", ip);
959 mono_exception_get_managed_backtrace (MonoException *exc)
963 text = g_string_new_len (NULL, 20);
965 if (!mono_get_eh_callbacks ()->mono_exception_walk_trace (exc, append_frame_and_continue, text))
966 g_string_append (text, "managed backtrace not available\n");
968 return g_string_free (text, FALSE);
972 mono_exception_handle_get_native_backtrace (MonoExceptionHandle exc)
974 #ifdef HAVE_BACKTRACE_SYMBOLS
976 MonoArrayHandle arr = MONO_HANDLE_NEW(MonoArray, NULL);
981 MONO_HANDLE_GET (arr, exc, native_trace_ips);
983 if (MONO_HANDLE_IS_NULL(arr))
984 return g_strdup ("");
985 domain = mono_domain_get ();
986 len = mono_array_handle_length (arr);
987 text = g_string_new_len (NULL, len * 20);
989 void *addr = MONO_ARRAY_HANDLE_PIN (arr, gpointer, 0, &gchandle);
991 messages = backtrace_symbols (addr, len);
993 mono_gchandle_free (gchandle);
995 for (i = 0; i < len; ++i) {
997 MONO_HANDLE_ARRAY_GETVAL (ip, arr, gpointer, i);
998 MonoJitInfo *ji = mono_jit_info_table_find (mono_domain_get (), (char *)ip);
1000 char *msg = mono_debug_print_stack_frame (mono_jit_info_get_method (ji), (char*)ip - (char*)ji->code_start, domain);
1001 g_string_append_printf (text, "%s\n", msg);
1004 g_string_append_printf (text, "%s\n", messages [i]);
1009 return g_string_free (text, FALSE);
1011 return g_strdup ("");
1016 ves_icall_Mono_Runtime_GetNativeStackTrace (MonoExceptionHandle exc, MonoError *error)
1019 MonoStringHandle res;
1020 mono_error_init (error);
1023 mono_error_set_argument_null (error, "exception", "");
1024 return NULL_HANDLE_STRING;
1027 trace = mono_exception_handle_get_native_backtrace (exc);
1028 res = mono_string_new_handle (mono_domain_get (), trace, error);
1034 * mono_error_raise_exception:
1035 * @target_error: the exception to raise
1037 * Raises the exception of @target_error.
1038 * Does nothing if @target_error has a success error code.
1039 * Aborts in case of a double fault. This happens when it can't recover from an error caused by trying
1040 * to construct the first exception object.
1041 * The error object @target_error is cleaned up.
1044 mono_error_raise_exception (MonoError *target_error)
1046 MonoException *ex = mono_error_convert_to_exception (target_error);
1048 mono_raise_exception (ex);
1052 * mono_error_set_pending_exception:
1056 * If @error is set, convert it to an exception and set the pending exception for the current icall.
1057 * Returns TRUE if @error was set, or FALSE otherwise, so that you can write:
1058 * if (mono_error_set_pending_exception (error)) {
1059 * { ... cleanup code ... }
1064 mono_error_set_pending_exception (MonoError *error)
1066 MonoException *ex = mono_error_convert_to_exception (error);
1068 mono_set_pending_exception (ex);
1076 mono_install_unhandled_exception_hook (MonoUnhandledExceptionFunc func, void *user_data)
1078 unhandled_exception_hook = func;
1079 unhandled_exception_hook_data = user_data;
1083 mono_invoke_unhandled_exception_hook (MonoObject *exc)
1085 if (unhandled_exception_hook) {
1086 unhandled_exception_hook (exc, unhandled_exception_hook_data);
1088 MonoError inner_error;
1089 MonoObject *other = NULL;
1090 MonoString *str = mono_object_try_to_string (exc, &other, &inner_error);
1093 if (str && is_ok (&inner_error)) {
1094 msg = mono_string_to_utf8_checked (str, &inner_error);
1095 if (!is_ok (&inner_error)) {
1096 msg = g_strdup_printf ("Nested exception while formatting original exception");
1097 mono_error_cleanup (&inner_error);
1100 char *original_backtrace = mono_exception_get_managed_backtrace ((MonoException*)exc);
1101 char *nested_backtrace = mono_exception_get_managed_backtrace ((MonoException*)other);
1103 msg = g_strdup_printf ("Nested exception detected.\nOriginal Exception: %s\nNested exception:%s\n",
1104 original_backtrace, nested_backtrace);
1106 g_free (original_backtrace);
1107 g_free (nested_backtrace);
1109 msg = g_strdup ("Nested exception trying to figure out what went wrong");
1111 mono_runtime_printf_err ("[ERROR] FATAL UNHANDLED EXCEPTION: %s", msg);
1113 #if defined(HOST_IOS)
1114 g_assertion_message ("Terminating runtime due to unhandled exception");
1116 exit (mono_environment_exitcode_get ());
1120 g_assert_not_reached ();