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>
21 #include <mono/metadata/object-internals.h>
22 #include <mono/metadata/metadata-internals.h>
23 #include <mono/metadata/appdomain.h>
24 #include <mono/metadata/domain-internals.h>
25 #include <mono/metadata/mono-debug.h>
26 #include <mono/utils/mono-error-internals.h>
27 #include <mono/utils/mono-logger-internals.h>
29 #ifdef HAVE_EXECINFO_H
32 #include "class-init.h"
33 #include "icall-decl.h"
35 static MonoUnhandledExceptionFunc unhandled_exception_hook
= NULL
;
36 static gpointer unhandled_exception_hook_data
= NULL
;
38 static MonoExceptionHandle
39 mono_exception_new_by_name_domain (MonoDomain
*domain
, MonoImage
*image
,
40 const char* name_space
, const char *name
, MonoError
*error
);
42 static MonoExceptionHandle
43 mono_exception_new_argument_internal (const char *type
, const char *arg
, const char *msg
, MonoError
*error
);
46 * mono_exception_new_by_name:
47 * \param image the Mono image where to look for the class
48 * \param name_space the namespace for the class
49 * \param name class name
51 * Creates an exception of the given namespace/name class in the
54 * \returns the initialized exception instance.
56 static MonoExceptionHandle
57 mono_exception_new_by_name (MonoImage
*image
, const char *name_space
, const char *name
, MonoError
*error
)
59 return mono_exception_new_by_name_domain (mono_domain_get (), image
, name_space
, name
, error
);
63 * mono_exception_from_name:
64 * \param image the Mono image where to look for the class
65 * \param name_space the namespace for the class
66 * \param name class name
68 * Creates an exception of the given namespace/name class in the
71 * \returns the initialized exception instance.
74 mono_exception_from_name (MonoImage
*image
, const char *name_space
,
77 return mono_exception_from_name_domain (mono_domain_get (), image
, name_space
, name
);
81 * mono_exception_new_by_name_domain:
82 * \param domain Domain where the return object will be created.
83 * \param image the Mono image where to look for the class
84 * \param name_space the namespace for the class
85 * \param name class name
87 * Creates an exception object of the given namespace/name class on
90 * \returns the initialized exception instance.
92 static MonoExceptionHandle
93 mono_exception_new_by_name_domain (MonoDomain
*domain
, MonoImage
*image
,
94 const char* name_space
, const char *name
, MonoError
*error
)
96 HANDLE_FUNCTION_ENTER ();
98 MonoDomain
* const caller_domain
= mono_domain_get ();
100 MonoClass
* const klass
= mono_class_load_from_name (image
, name_space
, name
);
102 MonoObjectHandle o
= mono_object_new_handle (domain
, klass
, error
);
103 goto_if_nok (error
, return_null
);
105 if (domain
!= caller_domain
)
106 mono_domain_set_internal_with_options (domain
, TRUE
);
108 mono_runtime_object_init_handle (o
, error
);
109 mono_error_assert_ok (error
);
111 // Restore domain in success and error path.
112 if (domain
!= caller_domain
)
113 mono_domain_set_internal_with_options (caller_domain
, TRUE
);
115 goto_if_ok (error
, exit
);
117 MONO_HANDLE_ASSIGN (o
, NULL_HANDLE
);
119 HANDLE_FUNCTION_RETURN_REF (MonoException
, MONO_HANDLE_CAST (MonoException
, o
));
123 * mono_exception_from_name_domain:
124 * \param domain Domain where the return object will be created.
125 * \param image the Mono image where to look for the class
126 * \param name_space the namespace for the class
127 * \param name class name
129 * Creates an exception object of the given namespace/name class on
132 * \returns the initialized exception instance.
135 mono_exception_from_name_domain (MonoDomain
*domain
, MonoImage
*image
,
136 const char* name_space
, const char *name
)
138 HANDLE_FUNCTION_ENTER ();
140 MonoExceptionHandle ret
= mono_exception_new_by_name_domain (domain
, image
, name_space
, name
, error
);
141 mono_error_assert_ok (error
);
142 HANDLE_FUNCTION_RETURN_OBJ (ret
);
146 * mono_exception_from_token:
147 * \param image the Mono image where to look for the class
148 * \param token The type token of the class
150 * Creates an exception of the type given by \p token.
152 * \returns the initialized exception instance.
155 mono_exception_from_token (MonoImage
*image
, guint32 token
)
157 HANDLE_FUNCTION_ENTER ();
161 klass
= mono_class_get_checked (image
, token
, error
);
162 mono_error_assert_ok (error
);
164 MonoObjectHandle o
= mono_object_new_handle (mono_domain_get (), klass
, error
);
165 mono_error_assert_ok (error
);
167 mono_runtime_object_init_handle (o
, error
);
168 mono_error_assert_ok (error
);
170 HANDLE_FUNCTION_RETURN_OBJ (MONO_HANDLE_CAST (MonoException
, o
));
173 static MonoExceptionHandle
174 create_exception_two_strings (MonoClass
*klass
, MonoStringHandle a1
, MonoStringHandle a2
, MonoError
*error
)
176 HANDLE_FUNCTION_ENTER ();
178 MonoMethod
*method
= NULL
;
179 int const count
= 1 + !MONO_HANDLE_IS_NULL (a2
);
183 MonoObjectHandle o
= mono_object_new_handle (mono_domain_get (), klass
, error
);
184 mono_error_assert_ok (error
);
187 while ((m
= mono_class_get_methods (klass
, &iter
))) {
188 MonoMethodSignature
*sig
;
190 if (strcmp (".ctor", mono_method_get_name (m
)))
192 sig
= mono_method_signature_internal (m
);
193 if (sig
->param_count
!= count
)
196 if (sig
->params
[0]->type
!= MONO_TYPE_STRING
)
198 if (count
== 2 && sig
->params
[1]->type
!= MONO_TYPE_STRING
)
205 gpointer args
[ ] = { MONO_HANDLE_RAW (a1
), MONO_HANDLE_RAW (a2
) };
207 mono_runtime_invoke_handle_void (method
, o
, args
, error
);
209 o
= mono_new_null ();
211 HANDLE_FUNCTION_RETURN_REF (MonoException
, MONO_HANDLE_CAST (MonoException
, o
));
215 * mono_exception_from_name_two_strings:
216 * \param image the Mono image where to look for the class
217 * \param name_space the namespace for the class
218 * \param name class name
219 * \param a1 first string argument to pass
220 * \param a2 second string argument to pass
222 * Creates an exception from a constructor that takes two string
225 * \returns the initialized exception instance.
228 mono_exception_from_name_two_strings (MonoImage
*image
, const char *name_space
,
229 const char *name
, MonoString
*a1_raw
, MonoString
*a2_raw
)
231 HANDLE_FUNCTION_ENTER ();
233 MONO_HANDLE_DCL (MonoString
, a1
);
234 MONO_HANDLE_DCL (MonoString
, a2
);
235 MonoExceptionHandle ret
= mono_exception_from_name_two_strings_checked (image
, name_space
, name
, a1
, a2
, error
);
236 mono_error_cleanup (error
);
237 HANDLE_FUNCTION_RETURN_OBJ (ret
);
241 * mono_exception_from_name_two_strings_checked:
242 * \param image the Mono image where to look for the class
243 * \param name_space the namespace for the class
244 * \param name class name
245 * \param a1 first string argument to pass
246 * \param a2 second string argument to pass
247 * \param error set on error
249 * Creates an exception from a constructor that takes two string
252 * \returns the initialized exception instance. On failure returns
253 * NULL and sets \p error.
256 mono_exception_from_name_two_strings_checked (MonoImage
*image
, const char *name_space
,
257 const char *name
, MonoStringHandle a1
, MonoStringHandle a2
,
260 HANDLE_FUNCTION_ENTER ();
265 klass
= mono_class_load_from_name (image
, name_space
, name
);
267 HANDLE_FUNCTION_RETURN_REF (MonoException
, create_exception_two_strings (klass
, a1
, a2
, error
));
271 * mono_exception_new_by_name_msg:
272 * \param image the Mono image where to look for the class
273 * \param name_space the namespace for the class
274 * \param name class name
275 * \param msg the message to embed inside the exception
277 * Creates an exception and initializes its message field.
279 * \returns the initialized exception instance.
282 mono_exception_new_by_name_msg (MonoImage
*image
, const char *name_space
,
283 const char *name
, const char *msg
, MonoError
*error
)
285 HANDLE_FUNCTION_ENTER ();
287 MonoExceptionHandle ex
= mono_exception_new_by_name (image
, name_space
, name
, error
);
288 goto_if_nok (error
, return_null
);
291 MonoStringHandle msg_str
= mono_string_new_handle (MONO_HANDLE_DOMAIN (ex
), msg
, error
);
292 // FIXME? Maybe just ignore this error, the exception is close to correct.
293 goto_if_nok (error
, return_null
);
294 // ex->message = msg_str;
295 MONO_HANDLE_SET (ex
, message
, msg_str
);
299 MONO_HANDLE_ASSIGN (ex
, NULL_HANDLE
);
301 HANDLE_FUNCTION_RETURN_REF (MonoException
, ex
)
305 * mono_exception_from_name_msg:
306 * \param image the Mono image where to look for the class
307 * \param name_space the namespace for the class
308 * \param name class name
309 * \param msg the message to embed inside the exception
311 * Creates an exception and initializes its message field.
313 * \returns the initialized exception instance.
316 mono_exception_from_name_msg (MonoImage
*image
, const char *name_space
,
317 const char *name
, const char *msg
)
319 HANDLE_FUNCTION_ENTER ();
320 MonoExceptionHandle ex
;
321 MONO_ENTER_GC_UNSAFE
;
323 ex
= mono_exception_new_by_name_msg (image
, name_space
, name
, msg
, error
);
324 mono_error_cleanup (error
);
326 HANDLE_FUNCTION_RETURN_OBJ (ex
);
330 * mono_exception_from_token_two_strings:
332 * Same as mono_exception_from_name_two_strings, but lookup the exception class using
336 mono_exception_from_token_two_strings (MonoImage
*image
, guint32 token
, MonoString
*arg1_raw
, MonoString
*arg2_raw
)
338 HANDLE_FUNCTION_ENTER ();
340 MONO_HANDLE_DCL (MonoString
, arg1
);
341 MONO_HANDLE_DCL (MonoString
, arg2
);
342 MonoExceptionHandle ret
= mono_exception_from_token_two_strings_checked (image
, token
, arg1
, arg2
, error
);
343 mono_error_cleanup (error
);
344 HANDLE_FUNCTION_RETURN_OBJ (ret
);
348 * mono_exception_from_token_two_strings_checked:
350 * Same as mono_exception_from_name_two_strings, but lookup the exception class using
354 mono_exception_from_token_two_strings_checked (MonoImage
*image
, guint32 token
,
355 MonoStringHandle a1
, MonoStringHandle a2
,
358 HANDLE_FUNCTION_ENTER ();
364 klass
= mono_class_get_checked (image
, token
, error
);
365 mono_error_assert_ok (error
); /* FIXME handle the error. */
367 HANDLE_FUNCTION_RETURN_REF (MonoException
, create_exception_two_strings (klass
, a1
, a2
, error
));
371 * mono_get_exception_divide_by_zero:
372 * \returns a new instance of the \c System.DivideByZeroException
375 mono_get_exception_divide_by_zero (void)
377 return mono_exception_from_name (mono_get_corlib (), "System",
378 "DivideByZeroException");
382 * mono_get_exception_security:
383 * \returns a new instance of the \c System.Security.SecurityException
386 mono_get_exception_security (void)
388 return mono_exception_from_name (mono_get_corlib (), "System.Security",
389 "SecurityException");
393 * mono_exception_new_thread_abort:
394 * \returns a new instance of the \c System.Threading.ThreadAbortException
397 mono_exception_new_thread_abort (MonoError
*error
)
399 return mono_exception_new_by_name (mono_get_corlib (), "System.Threading", "ThreadAbortException", error
);
403 * mono_get_exception_thread_abort:
404 * \returns a new instance of the \c System.Threading.ThreadAbortException
407 mono_get_exception_thread_abort (void)
409 return mono_exception_from_name (mono_get_corlib (), "System.Threading",
410 "ThreadAbortException");
414 * mono_exception_new_thread_interrupted:
415 * \returns a new instance of the \c System.Threading.ThreadInterruptedException
418 mono_exception_new_thread_interrupted (MonoError
*error
)
420 return mono_exception_new_by_name (mono_get_corlib (), "System.Threading", "ThreadInterruptedException", error
);
424 * mono_get_exception_thread_interrupted:
425 * \returns a new instance of the \c System.Threading.ThreadInterruptedException
428 mono_get_exception_thread_interrupted (void)
430 return mono_exception_from_name (mono_get_corlib (), "System.Threading",
431 "ThreadInterruptedException");
435 * mono_get_exception_arithmetic:
436 * \returns a new instance of the \c System.ArithmeticException
439 mono_get_exception_arithmetic (void)
441 return mono_exception_from_name (mono_get_corlib (), "System",
442 "ArithmeticException");
446 * mono_get_exception_overflow:
447 * \returns a new instance of the \c System.OverflowException
450 mono_get_exception_overflow (void)
452 return mono_exception_from_name (mono_get_corlib (), "System",
453 "OverflowException");
457 * mono_get_exception_null_reference:
458 * \returns a new instance of the \c System.NullReferenceException
461 mono_get_exception_null_reference (void)
463 return mono_exception_from_name (mono_get_corlib (), "System",
464 "NullReferenceException");
468 * mono_get_exception_execution_engine:
469 * \param msg the message to pass to the user
470 * \returns a new instance of the \c System.ExecutionEngineException
473 mono_get_exception_execution_engine (const char *msg
)
475 MonoException
*result
;
476 MONO_ENTER_GC_UNSAFE
;
477 result
= mono_exception_from_name_msg (mono_get_corlib (), "System", "ExecutionEngineException", msg
);
483 * mono_get_exception_serialization:
484 * \param msg the message to pass to the user
485 * \returns a new instance of the \c System.Runtime.Serialization.SerializationException
488 mono_get_exception_serialization (const char *msg
)
490 return mono_exception_from_name_msg (mono_get_corlib (), "System.Runtime.Serialization", "SerializationException", msg
);
494 * mono_get_exception_invalid_cast:
495 * \returns a new instance of the \c System.InvalidCastException
498 mono_get_exception_invalid_cast ()
500 return mono_exception_from_name (mono_get_corlib (), "System", "InvalidCastException");
504 * mono_get_exception_invalid_operation:
505 * \param msg the message to pass to the user
506 * \returns a new instance of the \c System.InvalidOperationException
509 mono_get_exception_invalid_operation (const char *msg
)
511 return mono_exception_from_name_msg (mono_get_corlib (), "System",
512 "InvalidOperationException", msg
);
516 mono_exception_new_invalid_operation (const char *msg
, MonoError
*error
)
518 return mono_exception_new_by_name_msg (mono_get_corlib (), "System",
519 "InvalidOperationException", msg
, error
);
523 * mono_get_exception_index_out_of_range:
524 * \returns a new instance of the \c System.IndexOutOfRangeException
527 mono_get_exception_index_out_of_range ()
529 return mono_exception_from_name (mono_get_corlib (), "System",
530 "IndexOutOfRangeException");
534 * mono_get_exception_array_type_mismatch:
535 * \returns a new instance of the \c System.ArrayTypeMismatchException
538 mono_get_exception_array_type_mismatch (void)
540 return mono_exception_from_name (mono_get_corlib (), "System",
541 "ArrayTypeMismatchException");
545 * mono_get_exception_type_load:
546 * \param class_name the name of the class that could not be loaded
547 * \param assembly_name the assembly where the class was looked up.
548 * \returns a new instance of the \c System.TypeLoadException
551 mono_get_exception_type_load (MonoString
*class_name_raw
, char *assembly_name
)
554 HANDLE_FUNCTION_ENTER ();
555 MONO_HANDLE_DCL (MonoString
, class_name
);
556 MonoStringHandle s
= NULL_HANDLE_STRING
;
557 MonoDomain
* const domain
= mono_domain_get ();
559 s
= mono_string_new_handle (domain
, assembly_name
, error
);
560 mono_error_assert_ok (error
);
562 s
= mono_string_empty_handle (domain
);
564 MonoExceptionHandle ret
= mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System",
565 "TypeLoadException", class_name
, s
, error
);
566 mono_error_assert_ok (error
);
567 HANDLE_FUNCTION_RETURN_OBJ (ret
);
571 * mono_get_exception_not_implemented:
572 * \param msg the message to pass to the user
573 * \returns a new instance of the \c System.NotImplementedException
576 mono_get_exception_not_implemented (const char *msg
)
578 return mono_exception_from_name_msg (mono_get_corlib (), "System", "NotImplementedException", msg
);
582 * mono_get_exception_not_supported:
583 * \param msg the message to pass to the user
584 * \returns a new instance of the \c System.NotSupportedException
587 mono_get_exception_not_supported (const char *msg
)
589 return mono_exception_from_name_msg (mono_get_corlib (), "System", "NotSupportedException", msg
);
593 * mono_get_exception_missing_member:
594 * \param exception_type the specific exception type for the specific member type, i.e. field or method
595 * \param class_name the class where the lookup was performed.
596 * \param member_name the name of the missing method.
597 * \returns a new instance of the \c exception_type (MissingFieldException or MissingMethodException)
599 static MonoException
*
600 mono_get_exception_missing_member (const char *exception_type
, const char *class_name
, const char *member_name
)
602 HANDLE_FUNCTION_ENTER ();
604 MonoDomain
* const domain
= mono_domain_get ();
605 MonoStringHandle s1
= mono_string_new_handle (domain
, class_name
, error
);
606 mono_error_assert_ok (error
);
607 MonoStringHandle s2
= mono_string_new_handle (domain
, member_name
, error
);
608 mono_error_assert_ok (error
);
610 MonoExceptionHandle ret
= mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System",
611 exception_type
, s1
, s2
, error
);
612 mono_error_assert_ok (error
);
613 HANDLE_FUNCTION_RETURN_OBJ (ret
);
617 * mono_get_exception_missing_method:
618 * \param class_name the class where the lookup was performed.
619 * \param member_name the name of the missing method.
620 * \returns a new instance of the \c System.MissingMethodException
623 mono_get_exception_missing_method (const char *class_name
, const char *member_name
)
625 return mono_get_exception_missing_member ("MissingMethodException", class_name
, member_name
);
629 * mono_get_exception_missing_field:
630 * \param class_name the class where the lookup was performed
631 * \param member_name the name of the missing field.
632 * \returns a new instance of the \c System.MissingFieldException
635 mono_get_exception_missing_field (const char *class_name
, const char *member_name
)
637 return mono_get_exception_missing_member ("MissingFieldException", class_name
, member_name
);
641 * mono_get_exception_argument_internal:
642 * \param type the actual type
643 * \param arg the name of the argument that is invalid or null, etc.
644 * \param msg optional message
645 * \returns a new instance of the \c System.ArgumentException or derived
647 static MonoException
*
648 mono_get_exception_argument_internal (const char *type
, const char *arg
, const char *msg
)
650 HANDLE_FUNCTION_ENTER ();
652 MonoExceptionHandle ex
= mono_exception_new_argument_internal (type
, arg
, msg
, error
);
653 mono_error_cleanup (error
);
654 HANDLE_FUNCTION_RETURN_OBJ (ex
);
658 * mono_get_exception_argument_null:
659 * \param arg the name of the argument that is null
660 * \returns a new instance of the \c System.ArgumentNullException
663 mono_get_exception_argument_null (const char *arg
)
666 MONO_ENTER_GC_UNSAFE
;
667 ex
= mono_get_exception_argument_internal ("ArgumentNullException", arg
, NULL
);
673 * mono_get_exception_argument:
674 * \param arg the name of the invalid argument.
675 * \returns a new instance of the \c System.ArgumentException
678 mono_get_exception_argument (const char *arg
, const char *msg
)
680 return mono_get_exception_argument_internal ("ArgumentException", arg
, msg
);
683 TYPED_HANDLE_DECL (MonoArgumentException
);
685 static MonoExceptionHandle
686 mono_exception_new_argument_internal (const char *type
, const char *arg
, const char *msg
, MonoError
*error
)
688 MonoExceptionHandle ex
= mono_exception_new_by_name_msg (mono_get_corlib (), "System", type
, msg
, error
);
690 if (arg
&& !MONO_HANDLE_IS_NULL (ex
)) {
691 MonoArgumentExceptionHandle argex
= MONO_HANDLE_CAST (MonoArgumentException
, ex
);
692 MonoStringHandle arg_str
= mono_string_new_handle (MONO_HANDLE_DOMAIN (ex
), arg
, error
);
693 MONO_HANDLE_SET (argex
, param_name
, arg_str
);
699 mono_exception_new_argument (const char *arg
, const char *msg
, MonoError
*error
)
701 return mono_exception_new_argument_internal ("ArgumentException", arg
, msg
, error
);
705 mono_exception_new_argument_null (const char *arg
, MonoError
*error
)
707 return mono_exception_new_argument_internal ("ArgumentNullException", arg
, NULL
, error
);
711 mono_exception_new_argument_out_of_range(const char *arg
, const char *msg
, MonoError
*error
)
713 return mono_exception_new_argument_internal ("ArgumentOutOfRangeException", arg
, msg
, error
);
717 mono_exception_new_serialization (const char *msg
, MonoError
*error
)
719 return mono_exception_new_by_name_msg (mono_get_corlib (),
720 "System.Runtime.Serialization", "SerializationException",
721 "Could not serialize unhandled exception.", error
);
725 * mono_get_exception_argument_out_of_range:
726 * \param arg the name of the out of range argument.
727 * \returns a new instance of the \c System.ArgumentOutOfRangeException
730 mono_get_exception_argument_out_of_range (const char *arg
)
732 return mono_get_exception_argument_internal ("ArgumentOutOfRangeException", arg
, NULL
);
736 * mono_get_exception_thread_state:
737 * \param msg the message to present to the user
738 * \returns a new instance of the \c System.Threading.ThreadStateException
741 mono_get_exception_thread_state (const char *msg
)
743 return mono_exception_from_name_msg (
744 mono_get_corlib (), "System.Threading", "ThreadStateException", msg
);
748 * mono_get_exception_io:
749 * \param msg the message to present to the user
750 * \returns a new instance of the \c System.IO.IOException
753 mono_get_exception_io (const char *msg
)
755 return mono_exception_from_name_msg (
756 mono_get_corlib (), "System.IO", "IOException", msg
);
760 * mono_get_exception_file_not_found:
761 * \param fname the name of the file not found.
762 * \returns a new instance of the \c System.IO.FileNotFoundException
765 mono_get_exception_file_not_found (MonoString
*fname_raw
)
767 HANDLE_FUNCTION_ENTER ();
769 MONO_HANDLE_DCL (MonoString
, fname
);
770 MonoExceptionHandle ret
= mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System.IO", "FileNotFoundException", fname
, fname
, error
);
771 mono_error_assert_ok (error
);
772 HANDLE_FUNCTION_RETURN_OBJ (ret
);
776 * mono_get_exception_file_not_found2:
777 * \param msg an informative message for the user.
778 * \param fname the name of the file not found.
779 * \returns a new instance of the \c System.IO.FileNotFoundException
782 mono_get_exception_file_not_found2 (const char *msg
, MonoString
*fname_raw
)
784 HANDLE_FUNCTION_ENTER ();
786 MONO_HANDLE_DCL (MonoString
, fname
);
787 MonoStringHandle s
= NULL_HANDLE_STRING
;
789 s
= mono_string_new_handle (mono_domain_get (), msg
, error
);
790 mono_error_assert_ok (error
);
792 MonoExceptionHandle ret
= mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System.IO", "FileNotFoundException", s
, fname
, error
);
793 mono_error_assert_ok (error
);
794 HANDLE_FUNCTION_RETURN_OBJ (ret
);
798 * mono_get_exception_type_initialization:
799 * \param type_name the name of the type that failed to initialize.
800 * \param inner the inner exception.
801 * \returns a new instance of the \c System.TypeInitializationException
804 mono_get_exception_type_initialization (const gchar
*type_name
, MonoException
* inner_raw
)
806 HANDLE_FUNCTION_ENTER ();
807 MONO_HANDLE_DCL (MonoException
, inner
);
809 MonoExceptionHandle ret
= mono_get_exception_type_initialization_handle (type_name
, inner
, error
);
810 if (!is_ok (error
)) {
811 ret
= MONO_HANDLE_CAST (MonoException
, mono_new_null ());
812 mono_error_cleanup (error
);
814 HANDLE_FUNCTION_RETURN_OBJ (ret
);
818 mono_get_exception_type_initialization_handle (const gchar
*type_name
, MonoExceptionHandle inner
, MonoError
*error
)
820 HANDLE_FUNCTION_ENTER ();
828 klass
= mono_class_load_from_name (mono_get_corlib (), "System", "TypeInitializationException");
830 mono_class_init_internal (klass
);
833 while ((method
= mono_class_get_methods (klass
, &iter
))) {
834 if (!strcmp (".ctor", mono_method_get_name (method
))) {
835 MonoMethodSignature
*sig
= mono_method_signature_internal (method
);
837 if (sig
->param_count
== 2 && sig
->params
[0]->type
== MONO_TYPE_STRING
&& mono_class_from_mono_type_internal (sig
->params
[1]) == mono_defaults
.exception_class
)
844 MonoDomain
* const domain
= mono_domain_get ();
845 MonoStringHandle type_name_str
= mono_string_new_handle (domain
, type_name
, error
);
846 mono_error_assert_ok (error
);
847 gpointer args
[ ] = { MONO_HANDLE_RAW (type_name_str
), MONO_HANDLE_RAW (inner
) };
849 MonoObjectHandle exc
= mono_object_new_handle (domain
, klass
, error
);
850 mono_error_assert_ok (error
);
852 mono_runtime_invoke_handle_void (method
, exc
, args
, error
);
853 goto_if_nok (error
, return_null
);
856 exc
= mono_new_null ();
858 HANDLE_FUNCTION_RETURN_REF (MonoException
, MONO_HANDLE_CAST (MonoException
, exc
));
862 * mono_get_exception_synchronization_lock:
863 * \param inner the inner exception.
864 * \returns a new instance of the \c System.SynchronizationLockException
867 mono_get_exception_synchronization_lock (const char *msg
)
869 return mono_exception_from_name_msg (mono_get_corlib (), "System.Threading", "SynchronizationLockException", msg
);
873 * mono_get_exception_cannot_unload_appdomain:
874 * \param inner the inner exception.
875 * \returns a new instance of the \c System.CannotUnloadAppDomainException
878 mono_get_exception_cannot_unload_appdomain (const char *msg
)
880 return mono_exception_from_name_msg (mono_get_corlib (), "System", "CannotUnloadAppDomainException", msg
);
884 * mono_get_exception_appdomain_unloaded
885 * \returns a new instance of the \c System.AppDomainUnloadedException
888 mono_get_exception_appdomain_unloaded (void)
890 return mono_exception_from_name (mono_get_corlib (), "System", "AppDomainUnloadedException");
894 * mono_get_exception_bad_image_format:
895 * \param msg an informative message for the user.
896 * \returns a new instance of the \c System.BadImageFormatException
899 mono_get_exception_bad_image_format (const char *msg
)
901 return mono_exception_from_name_msg (mono_get_corlib (), "System", "BadImageFormatException", msg
);
905 * mono_get_exception_bad_image_format2:
906 * \param msg an informative message for the user.
907 * \param fname The full name of the file with the invalid image.
908 * \returns a new instance of the \c System.BadImageFormatException
911 mono_get_exception_bad_image_format2 (const char *msg
, MonoString
*fname_raw
)
913 HANDLE_FUNCTION_ENTER ();
915 MonoStringHandle s
= NULL_HANDLE_STRING
;
916 MONO_HANDLE_DCL (MonoString
, fname
);
919 s
= mono_string_new_handle (mono_domain_get (), msg
, error
);
920 mono_error_assert_ok (error
);
923 MonoExceptionHandle ret
= mono_exception_from_name_two_strings_checked (
924 mono_get_corlib (), "System", "BadImageFormatException", s
, fname
, error
);
925 mono_error_assert_ok (error
);
926 HANDLE_FUNCTION_RETURN_OBJ (ret
);
930 * mono_get_exception_stack_overflow:
931 * \returns a new instance of the \c System.StackOverflowException
934 mono_get_exception_stack_overflow (void)
936 return mono_exception_from_name (mono_get_corlib (), "System", "StackOverflowException");
940 * mono_get_exception_out_of_memory:
941 * \returns a new instance of the \c System.OutOfMemoryException
944 mono_get_exception_out_of_memory (void)
946 return mono_exception_from_name (mono_get_corlib (), "System", "OutOfMemoryException");
950 mono_get_exception_out_of_memory_handle (void)
952 return MONO_HANDLE_NEW (MonoException
, mono_exception_from_name (mono_get_corlib (), "System", "OutOfMemoryException"));
956 * mono_get_exception_field_access:
957 * \returns a new instance of the \c System.FieldAccessException
960 mono_get_exception_field_access (void)
962 return mono_exception_from_name (mono_get_corlib (), "System", "FieldAccessException");
966 * mono_get_exception_field_access2:
967 * \param msg an informative message for the user.
968 * \returns a new instance of the \c System.FieldAccessException
971 mono_get_exception_field_access_msg (const char *msg
)
973 return mono_exception_from_name_msg (mono_get_corlib (), "System", "FieldAccessException", msg
);
977 * mono_get_exception_method_access:
978 * \returns a new instance of the \c System.MethodAccessException
981 mono_get_exception_method_access (void)
983 return mono_exception_from_name (mono_get_corlib (), "System", "MethodAccessException");
987 * mono_get_exception_method_access2:
988 * \param msg an informative message for the user.
989 * \returns a new instance of the \c System.MethodAccessException
992 mono_get_exception_method_access_msg (const char *msg
)
994 return mono_exception_from_name_msg (mono_get_corlib (), "System", "MethodAccessException", msg
);
998 * mono_get_exception_reflection_type_load:
999 * \param types an array of types that were defined in the moduled loaded.
1000 * \param exceptions an array of exceptions that were thrown during the type loading.
1001 * \returns a new instance of the \c System.Reflection.ReflectionTypeLoadException
1004 mono_get_exception_reflection_type_load (MonoArray
*types_raw
, MonoArray
*exceptions_raw
)
1006 HANDLE_FUNCTION_ENTER ();
1008 MONO_HANDLE_DCL (MonoArray
, types
);
1009 MONO_HANDLE_DCL (MonoArray
, exceptions
);
1010 MonoExceptionHandle ret
= mono_get_exception_reflection_type_load_checked (types
, exceptions
, error
);
1012 ret
= MONO_HANDLE_CAST (MonoException
, mono_new_null ());
1013 mono_error_cleanup (error
);
1014 HANDLE_FUNCTION_RETURN_OBJ (ret
);
1018 mono_get_exception_reflection_type_load_checked (MonoArrayHandle types
, MonoArrayHandle exceptions
, MonoError
*error
)
1020 HANDLE_FUNCTION_ENTER ();
1028 klass
= mono_class_load_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException");
1030 mono_class_init_internal (klass
);
1032 /* Find the Type[], Exception[] ctor */
1034 while ((method
= mono_class_get_methods (klass
, &iter
))) {
1035 if (!strcmp (".ctor", mono_method_get_name (method
))) {
1036 MonoMethodSignature
*sig
= mono_method_signature_internal (method
);
1038 if (sig
->param_count
== 2 && sig
->params
[0]->type
== MONO_TYPE_SZARRAY
&& sig
->params
[1]->type
== MONO_TYPE_SZARRAY
)
1045 MonoExceptionHandle exc
= MONO_HANDLE_CAST (MonoException
, MONO_HANDLE_NEW (MonoObject
, mono_object_new_checked (mono_domain_get (), klass
, error
)));
1046 mono_error_assert_ok (error
);
1048 gpointer args
[ ] = { MONO_HANDLE_RAW (types
), MONO_HANDLE_RAW (exceptions
) };
1050 mono_runtime_invoke_checked (method
, MONO_HANDLE_RAW (exc
), args
, error
);
1051 goto_if_nok (error
, return_null
);
1054 exc
= MONO_HANDLE_CAST (MonoException
, mono_new_null ());
1056 HANDLE_FUNCTION_RETURN_REF (MonoException
, exc
);
1060 * mono_get_exception_runtime_wrapped:
1063 mono_get_exception_runtime_wrapped (MonoObject
*wrapped_exception_raw
)
1065 HANDLE_FUNCTION_ENTER ();
1067 MONO_HANDLE_DCL (MonoObject
, wrapped_exception
);
1068 MonoExceptionHandle ret
= mono_get_exception_runtime_wrapped_handle (wrapped_exception
, error
);
1069 if (!is_ok (error
)) {
1070 mono_error_cleanup (error
);
1071 ret
= MONO_HANDLE_CAST (MonoException
, mono_new_null ());
1073 HANDLE_FUNCTION_RETURN_OBJ (ret
);
1077 mono_get_exception_runtime_wrapped_handle (MonoObjectHandle wrapped_exception
, MonoError
*error
)
1079 HANDLE_FUNCTION_ENTER ();
1084 klass
= mono_class_load_from_name (mono_get_corlib (), "System.Runtime.CompilerServices", "RuntimeWrappedException");
1086 MonoObjectHandle o
= mono_object_new_handle (mono_domain_get (), klass
, error
);
1087 mono_error_assert_ok (error
);
1088 g_assert (!MONO_HANDLE_IS_NULL (o
));
1090 method
= mono_class_get_method_from_name_checked (klass
, ".ctor", 1, 0, error
);
1091 mono_error_assert_ok (error
);
1094 gpointer args
[ ] = { MONO_HANDLE_RAW (wrapped_exception
) };
1096 mono_runtime_invoke_handle_void (method
, o
, args
, error
);
1097 goto_if_nok (error
, return_null
);
1100 o
= mono_new_null ();
1102 HANDLE_FUNCTION_RETURN_REF (MonoException
, MONO_HANDLE_CAST (MonoException
, o
));
1111 append_frame_and_continue (MonoMethod
*method
, gpointer ip
, size_t native_offset
, gboolean managed
, gpointer user_data
)
1113 MONO_ENTER_GC_UNSAFE
;
1114 MonoDomain
*domain
= mono_domain_get ();
1115 AppendFrameData
*data
= (AppendFrameData
*)user_data
;
1118 g_string_append (data
->text
, data
->prefix
);
1120 char *msg
= mono_debug_print_stack_frame (method
, native_offset
, domain
);
1121 g_string_append_printf (data
->text
, "%s\n", msg
);
1124 g_string_append_printf (data
->text
, "at <unknown native frame 0x%p>\n", ip
);
1126 MONO_EXIT_GC_UNSAFE
;
1131 mono_exception_try_get_managed_backtrace (MonoException
*exc
, const char *prefix
, char **result
)
1133 AppendFrameData data
;
1135 data
.text
= g_string_new_len (NULL
, 20);
1136 data
.prefix
= prefix
;
1138 if (!mono_get_eh_callbacks ()->mono_exception_walk_trace (exc
, append_frame_and_continue
, &data
)) {
1139 g_string_free (data
.text
, TRUE
);
1144 *result
= g_string_free (data
.text
, FALSE
);
1149 mono_exception_get_managed_backtrace (MonoException
*exc
)
1153 if (!mono_exception_try_get_managed_backtrace (exc
, NULL
, &result
))
1154 return g_strdup ("managed backtrace not available\n");
1160 mono_exception_handle_get_native_backtrace (MonoExceptionHandle exc
)
1162 #ifdef HAVE_BACKTRACE_SYMBOLS
1164 MonoArrayHandle arr
= MONO_HANDLE_NEW(MonoArray
, NULL
);
1169 MONO_HANDLE_GET (arr
, exc
, native_trace_ips
);
1171 if (MONO_HANDLE_IS_NULL(arr
))
1172 return g_strdup ("");
1173 domain
= mono_domain_get ();
1174 len
= mono_array_handle_length (arr
);
1175 text
= g_string_new_len (NULL
, len
* 20);
1176 MonoGCHandle gchandle
;
1177 gpointer
*addr
= MONO_ARRAY_HANDLE_PIN (arr
, gpointer
, 0, &gchandle
);
1179 messages
= backtrace_symbols (addr
, len
);
1181 mono_gchandle_free_internal (gchandle
);
1183 for (i
= 0; i
< len
; ++i
) {
1185 MONO_HANDLE_ARRAY_GETVAL (ip
, arr
, gpointer
, i
);
1186 MonoJitInfo
*ji
= mono_jit_info_table_find (domain
, ip
);
1188 char *msg
= mono_debug_print_stack_frame (mono_jit_info_get_method (ji
), (char*)ip
- (char*)ji
->code_start
, domain
);
1189 g_string_append_printf (text
, "%s\n", msg
);
1192 g_string_append_printf (text
, "%s\n", messages
[i
]);
1197 return g_string_free (text
, FALSE
);
1199 return g_strdup ("");
1204 ves_icall_Mono_Runtime_GetNativeStackTrace (MonoExceptionHandle exc
, MonoError
*error
)
1207 MonoStringHandle res
;
1210 if (MONO_HANDLE_IS_NULL (exc
)) {
1211 mono_error_set_argument_null (error
, "exception", "");
1212 return NULL_HANDLE_STRING
;
1215 trace
= mono_exception_handle_get_native_backtrace (exc
);
1216 res
= mono_string_new_handle (mono_domain_get (), trace
, error
);
1222 * mono_error_raise_exception_deprecated:
1223 * \param target_error the exception to raise
1225 * Raises the exception of \p target_error.
1226 * Does nothing if \p target_error has a success error code.
1227 * Aborts in case of a double fault. This happens when it can't recover from an error caused by trying
1228 * to construct the first exception object.
1229 * The error object \p target_error is cleaned up.
1232 mono_error_raise_exception_deprecated (MonoError
*target_error
)
1234 MonoException
*ex
= mono_error_convert_to_exception (target_error
);
1236 mono_raise_exception_deprecated (ex
);
1240 * mono_error_set_pending_exception_slow:
1241 * \param error The error
1242 * If \p error is set, convert it to an exception and set the pending exception for the current icall.
1243 * \returns TRUE if \p error was set, or FALSE otherwise, so that you can write:
1244 * if (mono_error_set_pending_exception (error)) {
1245 * { ... cleanup code ... }
1249 // For efficiency, call mono_error_set_pending_exception instead of mono_error_set_pending_exception_slow.
1251 mono_error_set_pending_exception_slow (MonoError
*error
)
1256 HANDLE_FUNCTION_ENTER ();
1258 MonoExceptionHandle ex
= mono_error_convert_to_exception_handle (error
);
1259 gboolean
const result
= !MONO_HANDLE_IS_NULL (ex
);
1261 mono_set_pending_exception_handle (ex
);
1263 HANDLE_FUNCTION_RETURN_VAL (result
);
1267 mono_install_unhandled_exception_hook (MonoUnhandledExceptionFunc func
, void *user_data
)
1269 unhandled_exception_hook
= func
;
1270 unhandled_exception_hook_data
= user_data
;
1274 mono_invoke_unhandled_exception_hook (MonoObject
*exc
)
1276 if (unhandled_exception_hook
) {
1277 unhandled_exception_hook (exc
, unhandled_exception_hook_data
);
1279 ERROR_DECL (inner_error
);
1280 MonoObject
*other
= NULL
;
1281 MonoString
*str
= mono_object_try_to_string (exc
, &other
, inner_error
);
1284 if (str
&& is_ok (inner_error
)) {
1285 msg
= mono_string_to_utf8_checked_internal (str
, inner_error
);
1286 if (!is_ok (inner_error
)) {
1287 msg
= g_strdup_printf ("Nested exception while formatting original exception");
1288 mono_error_cleanup (inner_error
);
1291 char *original_backtrace
= mono_exception_get_managed_backtrace ((MonoException
*)exc
);
1292 char *nested_backtrace
= mono_exception_get_managed_backtrace ((MonoException
*)other
);
1294 msg
= g_strdup_printf ("Nested exception detected.\nOriginal Exception: %s\nNested exception:%s\n",
1295 original_backtrace
, nested_backtrace
);
1297 g_free (original_backtrace
);
1298 g_free (nested_backtrace
);
1300 msg
= g_strdup ("Nested exception trying to figure out what went wrong");
1302 mono_runtime_printf_err ("[ERROR] FATAL UNHANDLED EXCEPTION: %s", msg
);
1304 #if defined(HOST_IOS)
1305 g_assertion_message ("Terminating runtime due to unhandled exception");
1307 exit (mono_environment_exitcode_get ());
1311 g_assert_not_reached ();
1315 mono_corlib_exception_new_with_args (const char *name_space
, const char *name
, const char *arg_0
, const char *arg_1
, MonoError
*error
)
1317 HANDLE_FUNCTION_ENTER ();
1319 MonoStringHandle str_0
= NULL_HANDLE_STRING
;
1320 MonoStringHandle str_1
= NULL_HANDLE_STRING
;
1321 MonoExceptionHandle ex
= MONO_HANDLE_CAST (MonoException
, NULL_HANDLE
);
1322 MonoDomain
* const domain
= mono_domain_get ();
1324 str_0
= arg_0
? mono_string_new_handle (domain
, arg_0
, error
) : NULL_HANDLE_STRING
;
1325 goto_if_nok (error
, return_null
);
1327 str_1
= arg_1
? mono_string_new_handle (domain
, arg_1
, error
) : NULL_HANDLE_STRING
;
1328 goto_if_nok (error
, return_null
);
1330 ex
= mono_exception_from_name_two_strings_checked (mono_defaults
.corlib
, name_space
, name
, str_0
, str_1
, error
);
1333 ex
= MONO_HANDLE_CAST (MonoException
, mono_new_null ());
1335 HANDLE_FUNCTION_RETURN_REF (MonoException
, ex
);
1339 mono_error_set_field_missing (MonoError
*error
, MonoClass
*klass
, const char *field_name
, MonoType
*sig
, const char *reason
, ...)
1344 res
= g_string_new ("Field not found: ");
1348 mono_type_get_desc (res
, sig
, TRUE
);
1349 g_string_append_c (res
, ' ');
1353 if (m_class_get_name_space (klass
)) {
1354 g_string_append (res
, m_class_get_name_space (klass
));
1355 g_string_append_c (res
, '.');
1357 g_string_append (res
, m_class_get_name (klass
));
1360 g_string_append (res
, "<unknown type>");
1363 g_string_append_c (res
, '.');
1366 g_string_append (res
, field_name
);
1368 g_string_append (res
, "<unknown field>");
1370 if (reason
&& *reason
) {
1372 va_start (args
, reason
);
1374 g_string_append (res
, " Due to: ");
1375 g_string_append_vprintf (res
, reason
, args
);
1379 g_string_free (res
, FALSE
);
1381 mono_error_set_specific (error
, MONO_ERROR_MISSING_FIELD
, result
);
1385 * Sets @error to a method missing error.
1388 mono_error_set_method_missing (MonoError
*error
, MonoClass
*klass
, const char *method_name
, MonoMethodSignature
*sig
, const char *reason
, ...)
1394 res
= g_string_new ("Method not found: ");
1397 mono_type_get_desc (res
, sig
->ret
, TRUE
);
1399 g_string_append_c (res
, ' ');
1403 if (m_class_get_name_space (klass
)) {
1404 g_string_append (res
, m_class_get_name_space (klass
));
1405 g_string_append_c (res
, '.');
1407 g_string_append (res
, m_class_get_name (klass
));
1410 g_string_append (res
, "<unknown type>");
1413 g_string_append_c (res
, '.');
1416 g_string_append (res
, method_name
);
1418 g_string_append (res
, "<unknown method>");
1421 if (sig
->generic_param_count
) {
1422 g_string_append_c (res
, '<');
1423 for (i
= 0; i
< sig
->generic_param_count
; ++i
) {
1425 g_string_append (res
, ",");
1426 g_string_append_printf (res
, "!%d", i
);
1428 g_string_append_c (res
, '>');
1431 g_string_append_c (res
, '(');
1432 for (i
= 0; i
< sig
->param_count
; ++i
) {
1434 g_string_append_c (res
, ',');
1435 mono_type_get_desc (res
, sig
->params
[i
], TRUE
);
1437 g_string_append_c (res
, ')');
1440 if (reason
&& *reason
) {
1442 va_start (args
, reason
);
1444 g_string_append (res
, " Due to: ");
1445 g_string_append_vprintf (res
, reason
, args
);
1449 g_string_free (res
, FALSE
);
1451 mono_error_set_specific (error
, MONO_ERROR_MISSING_METHOD
, result
);
1454 #define SET_ERROR_MSG(STR_VAR, FMT_STR) do { \
1456 va_start (__args, FMT_STR); \
1457 STR_VAR = g_strdup_vprintf (FMT_STR, __args); \
1462 * \p image_name argument will be g_strdup'd. Called must free passed value
1465 mono_error_set_bad_image_by_name (MonoError
*error
, const char *image_name
, const char *msg_format
, ...)
1468 SET_ERROR_MSG (str
, msg_format
);
1470 mono_error_set_specific (error
, MONO_ERROR_BAD_IMAGE
, str
);
1472 mono_error_set_first_argument (error
, image_name
);
1476 mono_error_set_bad_image (MonoError
*error
, MonoImage
*image
, const char *msg_format
, ...)
1479 SET_ERROR_MSG (str
, msg_format
);
1481 mono_error_set_specific (error
, MONO_ERROR_BAD_IMAGE
, str
);
1483 mono_error_set_first_argument (error
, mono_image_get_name (image
));
1487 mono_error_set_file_not_found (MonoError
*error
, const char *file_name
, const char *msg_format
, ...)
1490 SET_ERROR_MSG (str
, msg_format
);
1492 mono_error_set_specific (error
, MONO_ERROR_FILE_NOT_FOUND
, str
);
1494 mono_error_set_first_argument (error
, file_name
);
1498 mono_error_set_simple_file_not_found (MonoError
*error
, const char *file_name
, gboolean refection_only
)
1501 mono_error_set_file_not_found (error
, file_name
, "Cannot resolve dependency to assembly '%s' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.", file_name
);
1503 mono_error_set_file_not_found (error
, file_name
, "Could not load file or assembly '%s' or one of its dependencies.", file_name
);
1507 mono_error_set_argument_out_of_range (MonoError
*error
, const char *param_name
, const char *msg_format
, ...)
1510 SET_ERROR_MSG (str
, msg_format
);
1511 mono_error_set_specific (error
, MONO_ERROR_ARGUMENT_OUT_OF_RANGE
, str
);
1513 mono_error_set_first_argument (error
, param_name
);
1517 mono_error_convert_to_exception_handle (MonoError
*error
)
1519 //FIXMEcoop mono_error_convert_to_exception is raw pointer
1520 // The "optimization" here is important to significantly reduce handle usage.
1521 return is_ok (error
) ? MONO_HANDLE_CAST (MonoException
, NULL_HANDLE
)
1522 : MONO_HANDLE_NEW (MonoException
, mono_error_convert_to_exception (error
));