6 * Paolo Molaro (lupus@ximian.com)
7 * Dietmar Maurer (dietmar@ximian.com)
8 * Dick Porter (dick@ximian.com)
9 * Miguel de Icaza (miguel@ximian.com)
11 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
12 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
13 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
18 #include <mono/metadata/environment.h>
19 #include <mono/metadata/exception.h>
20 #include <mono/metadata/exception-internals.h>
22 #include <mono/metadata/object-internals.h>
23 #include <mono/metadata/metadata-internals.h>
24 #include <mono/metadata/appdomain.h>
25 #include <mono/metadata/mono-debug.h>
26 #include <mono/utils/mono-error-internals.h>
27 #include <mono/utils/mono-logger-internals.h>
30 #ifdef HAVE_EXECINFO_H
34 static MonoUnhandledExceptionFunc unhandled_exception_hook = NULL;
35 static gpointer unhandled_exception_hook_data = NULL;
38 * mono_exception_from_name:
39 * \param image the Mono image where to look for the class
40 * \param name_space the namespace for the class
41 * \param name class name
43 * Creates an exception of the given namespace/name class in the
46 * \returns the initialized exception instance.
49 mono_exception_from_name (MonoImage *image, const char *name_space,
52 return mono_exception_from_name_domain (mono_domain_get (), image, name_space, name);
56 * mono_exception_from_name_domain:
57 * \param domain Domain where the return object will be created.
58 * \param image the Mono image where to look for the class
59 * \param name_space the namespace for the class
60 * \param name class name
62 * Creates an exception object of the given namespace/name class on
65 * \returns the initialized exception instance.
68 mono_exception_from_name_domain (MonoDomain *domain, MonoImage *image,
69 const char* name_space, const char *name)
74 MonoDomain *caller_domain = mono_domain_get ();
76 klass = mono_class_load_from_name (image, name_space, name);
78 o = mono_object_new_checked (domain, klass, &error);
79 mono_error_assert_ok (&error);
81 if (domain != caller_domain)
82 mono_domain_set_internal (domain);
83 mono_runtime_object_init_checked (o, &error);
84 mono_error_assert_ok (&error);
86 if (domain != caller_domain)
87 mono_domain_set_internal (caller_domain);
89 return (MonoException *)o;
94 * mono_exception_from_token:
95 * \param image the Mono image where to look for the class
96 * \param token The type token of the class
98 * Creates an exception of the type given by \p token.
100 * \returns the initialized exception instance.
103 mono_exception_from_token (MonoImage *image, guint32 token)
109 klass = mono_class_get_checked (image, token, &error);
110 mono_error_assert_ok (&error);
112 o = mono_object_new_checked (mono_domain_get (), klass, &error);
113 mono_error_assert_ok (&error);
115 mono_runtime_object_init_checked (o, &error);
116 mono_error_assert_ok (&error);
118 return (MonoException *)o;
121 static MonoException *
122 create_exception_two_strings (MonoClass *klass, MonoString *a1, MonoString *a2, MonoError *error)
124 MonoDomain *domain = mono_domain_get ();
125 MonoMethod *method = NULL;
135 o = mono_object_new_checked (domain, klass, error);
136 mono_error_assert_ok (error);
139 while ((m = mono_class_get_methods (klass, &iter))) {
140 MonoMethodSignature *sig;
142 if (strcmp (".ctor", mono_method_get_name (m)))
144 sig = mono_method_signature (m);
145 if (sig->param_count != count)
148 if (sig->params [0]->type != MONO_TYPE_STRING)
150 if (count == 2 && sig->params [1]->type != MONO_TYPE_STRING)
159 mono_runtime_invoke_checked (method, o, args, error);
160 return_val_if_nok (error, NULL);
162 return (MonoException *) o;
166 * mono_exception_from_name_two_strings:
167 * \param image the Mono image where to look for the class
168 * \param name_space the namespace for the class
169 * \param name class name
170 * \param a1 first string argument to pass
171 * \param a2 second string argument to pass
173 * Creates an exception from a constructor that takes two string
176 * \returns the initialized exception instance.
179 mono_exception_from_name_two_strings (MonoImage *image, const char *name_space,
180 const char *name, MonoString *a1, MonoString *a2)
185 ret = mono_exception_from_name_two_strings_checked (image, name_space, name, a1, a2, &error);
186 mono_error_cleanup (&error);
191 * mono_exception_from_name_two_strings_checked:
192 * \param image the Mono image where to look for the class
193 * \param name_space the namespace for the class
194 * \param name class name
195 * \param a1 first string argument to pass
196 * \param a2 second string argument to pass
197 * \param error set on error
199 * Creates an exception from a constructor that takes two string
202 * \returns the initialized exception instance. On failure returns
203 * NULL and sets \p error.
206 mono_exception_from_name_two_strings_checked (MonoImage *image, const char *name_space,
207 const char *name, MonoString *a1, MonoString *a2,
213 klass = mono_class_load_from_name (image, name_space, name);
215 return create_exception_two_strings (klass, a1, a2, error);
219 * mono_exception_from_name_msg:
220 * \param image the Mono image where to look for the class
221 * \param name_space the namespace for the class
222 * \param name class name
223 * \param msg the message to embed inside the exception
225 * Creates an exception and initializes its message field.
227 * \returns the initialized exception instance.
230 mono_exception_from_name_msg (MonoImage *image, const char *name_space,
231 const char *name, const char *msg)
235 ex = mono_exception_from_name (image, name_space, name);
238 MONO_OBJECT_SETREF (ex, message, mono_string_new (mono_object_get_domain ((MonoObject*)ex), msg));
244 * mono_exception_from_token_two_strings:
246 * Same as mono_exception_from_name_two_strings, but lookup the exception class using
250 mono_exception_from_token_two_strings (MonoImage *image, guint32 token,
251 MonoString *a1, MonoString *a2)
255 ret = mono_exception_from_token_two_strings_checked (image, token, a1, a2, &error);
256 mono_error_cleanup (&error);
261 * mono_exception_from_token_two_strings_checked:
263 * Same as mono_exception_from_name_two_strings, but lookup the exception class using
267 mono_exception_from_token_two_strings_checked (MonoImage *image, guint32 token,
268 MonoString *a1, MonoString *a2,
275 klass = mono_class_get_checked (image, token, error);
276 mono_error_assert_ok (error); /* FIXME handle the error. */
278 return create_exception_two_strings (klass, a1, a2, error);
282 * mono_get_exception_divide_by_zero:
283 * \returns a new instance of the \c 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:
294 * \returns a new instance of the \c System.Security.SecurityException
297 mono_get_exception_security ()
299 return mono_exception_from_name (mono_get_corlib (), "System.Security",
300 "SecurityException");
304 * mono_get_exception_thread_abort:
305 * \returns a new instance of the \c System.Threading.ThreadAbortException
308 mono_get_exception_thread_abort ()
310 return mono_exception_from_name (mono_get_corlib (), "System.Threading",
311 "ThreadAbortException");
315 * mono_get_exception_thread_interrupted:
316 * \returns a new instance of the \c System.Threading.ThreadInterruptedException
319 mono_get_exception_thread_interrupted ()
321 return mono_exception_from_name (mono_get_corlib (), "System.Threading",
322 "ThreadInterruptedException");
326 * mono_get_exception_arithmetic:
327 * \returns a new instance of the \c System.ArithmeticException
330 mono_get_exception_arithmetic ()
332 return mono_exception_from_name (mono_get_corlib (), "System",
333 "ArithmeticException");
337 * mono_get_exception_overflow:
338 * \returns a new instance of the \c System.OverflowException
341 mono_get_exception_overflow ()
343 return mono_exception_from_name (mono_get_corlib (), "System",
344 "OverflowException");
348 * mono_get_exception_null_reference:
349 * \returns a new instance of the \c System.NullReferenceException
352 mono_get_exception_null_reference ()
354 return mono_exception_from_name (mono_get_corlib (), "System",
355 "NullReferenceException");
359 * mono_get_exception_execution_engine:
360 * \param msg the message to pass to the user
361 * \returns a new instance of the \c System.ExecutionEngineException
364 mono_get_exception_execution_engine (const char *msg)
366 return mono_exception_from_name_msg (mono_get_corlib (), "System", "ExecutionEngineException", msg);
370 * mono_get_exception_serialization:
371 * \param msg the message to pass to the user
372 * \returns a new instance of the \c System.Runtime.Serialization.SerializationException
375 mono_get_exception_serialization (const char *msg)
377 return mono_exception_from_name_msg (mono_get_corlib (), "System.Runtime.Serialization", "SerializationException", msg);
381 * mono_get_exception_invalid_cast:
382 * \returns a new instance of the \c System.InvalidCastException
385 mono_get_exception_invalid_cast ()
387 return mono_exception_from_name (mono_get_corlib (), "System", "InvalidCastException");
391 * mono_get_exception_invalid_operation:
392 * \param msg the message to pass to the user
393 * \returns a new instance of the \c System.InvalidOperationException
396 mono_get_exception_invalid_operation (const char *msg)
398 return mono_exception_from_name_msg (mono_get_corlib (), "System",
399 "InvalidOperationException", msg);
403 * mono_get_exception_index_out_of_range:
404 * \returns a new instance of the \c System.IndexOutOfRangeException
407 mono_get_exception_index_out_of_range ()
409 return mono_exception_from_name (mono_get_corlib (), "System",
410 "IndexOutOfRangeException");
414 * mono_get_exception_array_type_mismatch:
415 * \returns a new instance of the \c System.ArrayTypeMismatchException
418 mono_get_exception_array_type_mismatch ()
420 return mono_exception_from_name (mono_get_corlib (), "System",
421 "ArrayTypeMismatchException");
425 * mono_get_exception_type_load:
426 * \param class_name the name of the class that could not be loaded
427 * \param assembly_name the assembly where the class was looked up.
428 * \returns a new instance of the \c System.TypeLoadException
431 mono_get_exception_type_load (MonoString *class_name, char *assembly_name)
433 MonoString *s = assembly_name ? mono_string_new (mono_domain_get (), assembly_name) : mono_string_new (mono_domain_get (), "");
436 MonoException *ret = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System",
437 "TypeLoadException", class_name, s, &error);
438 mono_error_assert_ok (&error);
443 * mono_get_exception_not_implemented:
444 * \param msg the message to pass to the user
445 * \returns a new instance of the \c System.NotImplementedException
448 mono_get_exception_not_implemented (const char *msg)
450 return mono_exception_from_name_msg (mono_get_corlib (), "System", "NotImplementedException", msg);
454 * mono_get_exception_not_supported:
455 * \param msg the message to pass to the user
456 * \returns a new instance of the \c System.NotSupportedException
459 mono_get_exception_not_supported (const char *msg)
461 return mono_exception_from_name_msg (mono_get_corlib (), "System", "NotSupportedException", msg);
465 * mono_get_exception_missing_method:
466 * \param class_name the class where the lookup was performed.
467 * \param member_name the name of the missing method.
468 * \returns a new instance of the \c System.MissingMethodException
471 mono_get_exception_missing_method (const char *class_name, const char *member_name)
473 MonoString *s1 = mono_string_new (mono_domain_get (), class_name);
474 MonoString *s2 = mono_string_new (mono_domain_get (), member_name);
477 MonoException *ret = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System",
478 "MissingMethodException", s1, s2, &error);
479 mono_error_assert_ok (&error);
484 * mono_get_exception_missing_field:
485 * \param class_name the class where the lookup was performed
486 * \param member_name the name of the missing method.
487 * \returns a new instance of the \c System.MissingFieldException
490 mono_get_exception_missing_field (const char *class_name, const char *member_name)
492 MonoString *s1 = mono_string_new (mono_domain_get (), class_name);
493 MonoString *s2 = mono_string_new (mono_domain_get (), member_name);
496 MonoException *ret = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System",
497 "MissingFieldException", s1, s2, &error);
498 mono_error_assert_ok (&error);
503 * mono_get_exception_argument_null:
504 * \param arg the name of the argument that is null
505 * \returns a new instance of the \c System.ArgumentNullException
508 mono_get_exception_argument_null (const char *arg)
512 ex = mono_exception_from_name (
513 mono_get_corlib (), "System", "ArgumentNullException");
516 MonoArgumentException *argex = (MonoArgumentException *)ex;
517 MONO_OBJECT_SETREF (argex, param_name, mono_string_new (mono_object_get_domain ((MonoObject*)ex), arg));
524 * mono_get_exception_argument:
525 * \param arg the name of the invalid argument.
526 * \returns a new instance of the \c System.ArgumentException
529 mono_get_exception_argument (const char *arg, const char *msg)
533 ex = mono_exception_from_name_msg (
534 mono_get_corlib (), "System", "ArgumentException", msg);
537 MonoArgumentException *argex = (MonoArgumentException *)ex;
538 MONO_OBJECT_SETREF (argex, param_name, mono_string_new (mono_object_get_domain ((MonoObject*)ex), arg));
545 * mono_get_exception_argument_out_of_range:
546 * \param arg the name of the out of range argument.
547 * \returns a new instance of the \c System.ArgumentOutOfRangeException
550 mono_get_exception_argument_out_of_range (const char *arg)
554 ex = mono_exception_from_name (
555 mono_get_corlib (), "System", "ArgumentOutOfRangeException");
558 MonoArgumentException *argex = (MonoArgumentException *)ex;
559 MONO_OBJECT_SETREF (argex, param_name, mono_string_new (mono_object_get_domain ((MonoObject*)ex), arg));
566 * mono_get_exception_thread_state:
567 * \param msg the message to present to the user
568 * \returns a new instance of the \c System.Threading.ThreadStateException
571 mono_get_exception_thread_state (const char *msg)
573 return mono_exception_from_name_msg (
574 mono_get_corlib (), "System.Threading", "ThreadStateException", msg);
578 * mono_get_exception_io:
579 * \param msg the message to present to the user
580 * \returns a new instance of the \c System.IO.IOException
583 mono_get_exception_io (const char *msg)
585 return mono_exception_from_name_msg (
586 mono_get_corlib (), "System.IO", "IOException", msg);
590 * mono_get_exception_file_not_found:
591 * \param fname the name of the file not found.
592 * \returns a new instance of the \c System.IO.FileNotFoundException
595 mono_get_exception_file_not_found (MonoString *fname)
598 MonoException *ret = mono_exception_from_name_two_strings_checked (
599 mono_get_corlib (), "System.IO", "FileNotFoundException", fname, fname, &error);
600 mono_error_assert_ok (&error);
605 * mono_get_exception_file_not_found2:
606 * \param msg an informative message for the user.
607 * \param fname the name of the file not found.
608 * \returns a new instance of the \c System.IO.FileNotFoundException
611 mono_get_exception_file_not_found2 (const char *msg, MonoString *fname)
613 MonoString *s = msg ? mono_string_new (mono_domain_get (), msg) : NULL;
616 MonoException *ret = mono_exception_from_name_two_strings_checked (
617 mono_get_corlib (), "System.IO", "FileNotFoundException", s, fname, &error);
618 mono_error_assert_ok (&error);
623 * mono_get_exception_type_initialization:
624 * \param type_name the name of the type that failed to initialize.
625 * \param inner the inner exception.
626 * \returns a new instance of the \c System.TypeInitializationException
629 mono_get_exception_type_initialization (const gchar *type_name, MonoException *inner)
632 MonoException *ret = mono_get_exception_type_initialization_checked (type_name, inner, &error);
633 if (!is_ok (&error)) {
634 mono_error_cleanup (&error);
642 mono_get_exception_type_initialization_checked (const gchar *type_name, MonoException *inner, MonoError *error)
650 klass = mono_class_load_from_name (mono_get_corlib (), "System", "TypeInitializationException");
652 mono_class_init (klass);
655 while ((method = mono_class_get_methods (klass, &iter))) {
656 if (!strcmp (".ctor", mono_method_get_name (method))) {
657 MonoMethodSignature *sig = mono_method_signature (method);
659 if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_STRING && mono_class_from_mono_type (sig->params [1]) == mono_defaults.exception_class)
666 args [0] = mono_string_new (mono_domain_get (), type_name);
669 exc = mono_object_new_checked (mono_domain_get (), klass, error);
670 mono_error_assert_ok (error);
672 mono_runtime_invoke_checked (method, exc, args, error);
673 return_val_if_nok (error, NULL);
675 return (MonoException *) exc;
679 * mono_get_exception_synchronization_lock:
680 * \param inner the inner exception.
681 * \returns a new instance of the \c System.SynchronizationLockException
684 mono_get_exception_synchronization_lock (const char *msg)
686 return mono_exception_from_name_msg (mono_get_corlib (), "System.Threading", "SynchronizationLockException", msg);
690 * mono_get_exception_cannot_unload_appdomain:
691 * \param inner the inner exception.
692 * \returns a new instance of the \c System.CannotUnloadAppDomainException
695 mono_get_exception_cannot_unload_appdomain (const char *msg)
697 return mono_exception_from_name_msg (mono_get_corlib (), "System", "CannotUnloadAppDomainException", msg);
701 * mono_get_exception_appdomain_unloaded
702 * \returns a new instance of the \c System.AppDomainUnloadedException
705 mono_get_exception_appdomain_unloaded (void)
707 return mono_exception_from_name (mono_get_corlib (), "System", "AppDomainUnloadedException");
711 * mono_get_exception_bad_image_format:
712 * \param msg an informative message for the user.
713 * \returns a new instance of the \c System.BadImageFormatException
716 mono_get_exception_bad_image_format (const char *msg)
718 return mono_exception_from_name_msg (mono_get_corlib (), "System", "BadImageFormatException", msg);
722 * mono_get_exception_bad_image_format2:
723 * \param msg an informative message for the user.
724 * \param fname The full name of the file with the invalid image.
725 * \returns a new instance of the \c System.BadImageFormatException
728 mono_get_exception_bad_image_format2 (const char *msg, MonoString *fname)
730 MonoString *s = msg ? mono_string_new (mono_domain_get (), msg) : NULL;
733 MonoException *ret = mono_exception_from_name_two_strings_checked (
734 mono_get_corlib (), "System", "BadImageFormatException", s, fname, &error);
735 mono_error_assert_ok (&error);
740 * mono_get_exception_stack_overflow:
741 * \returns a new instance of the \c System.StackOverflowException
744 mono_get_exception_stack_overflow (void)
746 return mono_exception_from_name (mono_get_corlib (), "System", "StackOverflowException");
750 * mono_get_exception_out_of_memory:
751 * \returns a new instance of the \c System.OutOfMemoryException
754 mono_get_exception_out_of_memory (void)
756 return mono_exception_from_name (mono_get_corlib (), "System", "OutOfMemoryException");
760 * mono_get_exception_field_access:
761 * \returns a new instance of the \c System.FieldAccessException
764 mono_get_exception_field_access (void)
766 return mono_exception_from_name (mono_get_corlib (), "System", "FieldAccessException");
770 * mono_get_exception_field_access2:
771 * \param msg an informative message for the user.
772 * \returns a new instance of the \c System.FieldAccessException
775 mono_get_exception_field_access_msg (const char *msg)
777 return mono_exception_from_name_msg (mono_get_corlib (), "System", "FieldAccessException", msg);
781 * mono_get_exception_method_access:
782 * \returns a new instance of the \c System.MethodAccessException
785 mono_get_exception_method_access (void)
787 return mono_exception_from_name (mono_get_corlib (), "System", "MethodAccessException");
791 * mono_get_exception_method_access2:
792 * \param msg an informative message for the user.
793 * \returns a new instance of the \c System.MethodAccessException
796 mono_get_exception_method_access_msg (const char *msg)
798 return mono_exception_from_name_msg (mono_get_corlib (), "System", "MethodAccessException", msg);
802 * mono_get_exception_reflection_type_load:
803 * \param types an array of types that were defined in the moduled loaded.
804 * \param exceptions an array of exceptions that were thrown during the type loading.
805 * \returns a new instance of the \c System.Reflection.ReflectionTypeLoadException
808 mono_get_exception_reflection_type_load (MonoArray *types_raw, MonoArray *exceptions_raw)
810 HANDLE_FUNCTION_ENTER ();
812 MONO_HANDLE_DCL (MonoArray, types);
813 MONO_HANDLE_DCL (MonoArray, exceptions);
814 MonoExceptionHandle ret = mono_get_exception_reflection_type_load_checked (types, exceptions, &error);
815 if (is_ok (&error)) {
816 mono_error_cleanup (&error);
817 ret = MONO_HANDLE_CAST (MonoException, NULL_HANDLE);
822 HANDLE_FUNCTION_RETURN_OBJ (ret);
827 mono_get_exception_reflection_type_load_checked (MonoArrayHandle types, MonoArrayHandle exceptions, MonoError *error)
835 klass = mono_class_load_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException");
837 mono_class_init (klass);
839 /* Find the Type[], Exception[] ctor */
841 while ((method = mono_class_get_methods (klass, &iter))) {
842 if (!strcmp (".ctor", mono_method_get_name (method))) {
843 MonoMethodSignature *sig = mono_method_signature (method);
845 if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_SZARRAY && sig->params [1]->type == MONO_TYPE_SZARRAY)
852 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_object_new_checked (mono_domain_get (), klass, error));
853 mono_error_assert_ok (error);
856 args [0] = MONO_HANDLE_RAW (types);
857 args [1] = MONO_HANDLE_RAW (exceptions);
859 mono_runtime_invoke_checked (method, MONO_HANDLE_RAW (exc), args, error);
860 return_val_if_nok (error, MONO_HANDLE_CAST (MonoException, NULL_HANDLE));
866 * mono_get_exception_runtime_wrapped:
869 mono_get_exception_runtime_wrapped (MonoObject *wrapped_exception)
872 MonoException *ret = mono_get_exception_runtime_wrapped_checked (wrapped_exception, &error);
873 if (!is_ok (&error)) {
874 mono_error_cleanup (&error);
882 mono_get_exception_runtime_wrapped_checked (MonoObject *wrapped_exception, MonoError *error)
887 MonoDomain *domain = mono_domain_get ();
888 gpointer params [16];
890 klass = mono_class_load_from_name (mono_get_corlib (), "System.Runtime.CompilerServices", "RuntimeWrappedException");
892 o = mono_object_new_checked (domain, klass, error);
893 mono_error_assert_ok (error);
894 g_assert (o != NULL);
896 method = mono_class_get_method_from_name (klass, ".ctor", 1);
899 params [0] = wrapped_exception;
901 mono_runtime_invoke_checked (method, o, params, error);
902 return_val_if_nok (error, NULL);
904 return (MonoException *)o;
908 append_frame_and_continue (MonoMethod *method, gpointer ip, size_t native_offset, gboolean managed, gpointer user_data)
910 MonoDomain *domain = mono_domain_get ();
911 GString *text = (GString*)user_data;
914 char *msg = mono_debug_print_stack_frame (method, native_offset, domain);
915 g_string_append_printf (text, "%s\n", msg);
918 g_string_append_printf (text, "<unknown native frame 0x%x>\n", ip);
925 mono_exception_get_managed_backtrace (MonoException *exc)
929 text = g_string_new_len (NULL, 20);
931 if (!mono_get_eh_callbacks ()->mono_exception_walk_trace (exc, append_frame_and_continue, text))
932 g_string_append (text, "managed backtrace not available\n");
934 return g_string_free (text, FALSE);
938 mono_exception_handle_get_native_backtrace (MonoExceptionHandle exc)
940 #ifdef HAVE_BACKTRACE_SYMBOLS
942 MonoArrayHandle arr = MONO_HANDLE_NEW(MonoArray, NULL);
947 MONO_HANDLE_GET (arr, exc, native_trace_ips);
949 if (MONO_HANDLE_IS_NULL(arr))
950 return g_strdup ("");
951 domain = mono_domain_get ();
952 len = mono_array_handle_length (arr);
953 text = g_string_new_len (NULL, len * 20);
955 void *addr = MONO_ARRAY_HANDLE_PIN (arr, gpointer, 0, &gchandle);
957 messages = backtrace_symbols (addr, len);
959 mono_gchandle_free (gchandle);
961 for (i = 0; i < len; ++i) {
963 MONO_HANDLE_ARRAY_GETVAL (ip, arr, gpointer, i);
964 MonoJitInfo *ji = mono_jit_info_table_find (mono_domain_get (), (char *)ip);
966 char *msg = mono_debug_print_stack_frame (mono_jit_info_get_method (ji), (char*)ip - (char*)ji->code_start, domain);
967 g_string_append_printf (text, "%s\n", msg);
970 g_string_append_printf (text, "%s\n", messages [i]);
975 return g_string_free (text, FALSE);
977 return g_strdup ("");
982 ves_icall_Mono_Runtime_GetNativeStackTrace (MonoExceptionHandle exc, MonoError *error)
985 MonoStringHandle res;
989 mono_error_set_argument_null (error, "exception", "");
990 return NULL_HANDLE_STRING;
993 trace = mono_exception_handle_get_native_backtrace (exc);
994 res = mono_string_new_handle (mono_domain_get (), trace, error);
1000 * mono_error_raise_exception:
1001 * \param target_error the exception to raise
1003 * Raises the exception of \p target_error.
1004 * Does nothing if \p target_error has a success error code.
1005 * Aborts in case of a double fault. This happens when it can't recover from an error caused by trying
1006 * to construct the first exception object.
1007 * The error object \p target_error is cleaned up.
1010 mono_error_raise_exception (MonoError *target_error)
1012 MonoException *ex = mono_error_convert_to_exception (target_error);
1014 mono_raise_exception (ex);
1018 * mono_error_set_pending_exception:
1019 * \param error The error
1020 * If \p error is set, convert it to an exception and set the pending exception for the current icall.
1021 * \returns TRUE if \p error was set, or FALSE otherwise, so that you can write:
1022 * if (mono_error_set_pending_exception (error)) {
1023 * { ... cleanup code ... }
1028 mono_error_set_pending_exception (MonoError *error)
1030 MonoException *ex = mono_error_convert_to_exception (error);
1032 mono_set_pending_exception (ex);
1040 mono_install_unhandled_exception_hook (MonoUnhandledExceptionFunc func, void *user_data)
1042 unhandled_exception_hook = func;
1043 unhandled_exception_hook_data = user_data;
1047 mono_invoke_unhandled_exception_hook (MonoObject *exc)
1049 if (unhandled_exception_hook) {
1050 unhandled_exception_hook (exc, unhandled_exception_hook_data);
1052 MonoError inner_error;
1053 MonoObject *other = NULL;
1054 MonoString *str = mono_object_try_to_string (exc, &other, &inner_error);
1057 if (str && is_ok (&inner_error)) {
1058 msg = mono_string_to_utf8_checked (str, &inner_error);
1059 if (!is_ok (&inner_error)) {
1060 msg = g_strdup_printf ("Nested exception while formatting original exception");
1061 mono_error_cleanup (&inner_error);
1064 char *original_backtrace = mono_exception_get_managed_backtrace ((MonoException*)exc);
1065 char *nested_backtrace = mono_exception_get_managed_backtrace ((MonoException*)other);
1067 msg = g_strdup_printf ("Nested exception detected.\nOriginal Exception: %s\nNested exception:%s\n",
1068 original_backtrace, nested_backtrace);
1070 g_free (original_backtrace);
1071 g_free (nested_backtrace);
1073 msg = g_strdup ("Nested exception trying to figure out what went wrong");
1075 mono_runtime_printf_err ("[ERROR] FATAL UNHANDLED EXCEPTION: %s", msg);
1077 #if defined(HOST_IOS)
1078 g_assertion_message ("Terminating runtime due to unhandled exception");
1080 exit (mono_environment_exitcode_get ());
1084 g_assert_not_reached ();