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
)
204 gpointer args
[ ] = { MONO_HANDLE_RAW (a1
), MONO_HANDLE_RAW (a2
) };
206 mono_runtime_invoke_handle_void (method
, o
, args
, error
);
208 o
= mono_new_null ();
210 HANDLE_FUNCTION_RETURN_REF (MonoException
, MONO_HANDLE_CAST (MonoException
, o
));
214 * mono_exception_from_name_two_strings:
215 * \param image the Mono image where to look for the class
216 * \param name_space the namespace for the class
217 * \param name class name
218 * \param a1 first string argument to pass
219 * \param a2 second string argument to pass
221 * Creates an exception from a constructor that takes two string
224 * \returns the initialized exception instance.
227 mono_exception_from_name_two_strings (MonoImage
*image
, const char *name_space
,
228 const char *name
, MonoString
*a1_raw
, MonoString
*a2_raw
)
230 HANDLE_FUNCTION_ENTER ();
232 MONO_HANDLE_DCL (MonoString
, a1
);
233 MONO_HANDLE_DCL (MonoString
, a2
);
234 MonoExceptionHandle ret
= mono_exception_from_name_two_strings_checked (image
, name_space
, name
, a1
, a2
, error
);
235 mono_error_cleanup (error
);
236 HANDLE_FUNCTION_RETURN_OBJ (ret
);
240 * mono_exception_from_name_two_strings_checked:
241 * \param image the Mono image where to look for the class
242 * \param name_space the namespace for the class
243 * \param name class name
244 * \param a1 first string argument to pass
245 * \param a2 second string argument to pass
246 * \param error set on error
248 * Creates an exception from a constructor that takes two string
251 * \returns the initialized exception instance. On failure returns
252 * NULL and sets \p error.
255 mono_exception_from_name_two_strings_checked (MonoImage
*image
, const char *name_space
,
256 const char *name
, MonoStringHandle a1
, MonoStringHandle a2
,
259 HANDLE_FUNCTION_ENTER ();
264 klass
= mono_class_load_from_name (image
, name_space
, name
);
266 HANDLE_FUNCTION_RETURN_REF (MonoException
, create_exception_two_strings (klass
, a1
, a2
, error
));
270 * mono_exception_new_by_name_msg:
271 * \param image the Mono image where to look for the class
272 * \param name_space the namespace for the class
273 * \param name class name
274 * \param msg the message to embed inside the exception
276 * Creates an exception and initializes its message field.
278 * \returns the initialized exception instance.
281 mono_exception_new_by_name_msg (MonoImage
*image
, const char *name_space
,
282 const char *name
, const char *msg
, MonoError
*error
)
284 HANDLE_FUNCTION_ENTER ();
286 MonoExceptionHandle ex
= mono_exception_new_by_name (image
, name_space
, name
, error
);
287 goto_if_nok (error
, return_null
);
290 MonoStringHandle msg_str
= mono_string_new_handle (MONO_HANDLE_DOMAIN (ex
), msg
, error
);
291 // FIXME? Maybe just ignore this error, the exception is close to correct.
292 goto_if_nok (error
, return_null
);
293 // ex->message = msg_str;
294 MONO_HANDLE_SET (ex
, message
, msg_str
);
298 MONO_HANDLE_ASSIGN (ex
, NULL_HANDLE
);
300 HANDLE_FUNCTION_RETURN_REF (MonoException
, ex
)
304 * mono_exception_from_name_msg:
305 * \param image the Mono image where to look for the class
306 * \param name_space the namespace for the class
307 * \param name class name
308 * \param msg the message to embed inside the exception
310 * Creates an exception and initializes its message field.
312 * \returns the initialized exception instance.
315 mono_exception_from_name_msg (MonoImage
*image
, const char *name_space
,
316 const char *name
, const char *msg
)
318 HANDLE_FUNCTION_ENTER ();
319 MonoExceptionHandle ex
;
320 MONO_ENTER_GC_UNSAFE
;
322 ex
= mono_exception_new_by_name_msg (image
, name_space
, name
, msg
, error
);
323 mono_error_cleanup (error
);
325 HANDLE_FUNCTION_RETURN_OBJ (ex
);
329 * mono_exception_from_token_two_strings:
331 * Same as mono_exception_from_name_two_strings, but lookup the exception class using
335 mono_exception_from_token_two_strings (MonoImage
*image
, guint32 token
, MonoString
*arg1_raw
, MonoString
*arg2_raw
)
337 HANDLE_FUNCTION_ENTER ();
339 MONO_HANDLE_DCL (MonoString
, arg1
);
340 MONO_HANDLE_DCL (MonoString
, arg2
);
341 MonoExceptionHandle ret
= mono_exception_from_token_two_strings_checked (image
, token
, arg1
, arg2
, error
);
342 mono_error_cleanup (error
);
343 HANDLE_FUNCTION_RETURN_OBJ (ret
);
347 * mono_exception_from_token_two_strings_checked:
349 * Same as mono_exception_from_name_two_strings, but lookup the exception class using
353 mono_exception_from_token_two_strings_checked (MonoImage
*image
, guint32 token
,
354 MonoStringHandle a1
, MonoStringHandle a2
,
357 HANDLE_FUNCTION_ENTER ();
363 klass
= mono_class_get_checked (image
, token
, error
);
364 mono_error_assert_ok (error
); /* FIXME handle the error. */
366 HANDLE_FUNCTION_RETURN_REF (MonoException
, create_exception_two_strings (klass
, a1
, a2
, error
));
370 * mono_get_exception_divide_by_zero:
371 * \returns a new instance of the \c System.DivideByZeroException
374 mono_get_exception_divide_by_zero (void)
376 return mono_exception_from_name (mono_get_corlib (), "System",
377 "DivideByZeroException");
381 * mono_get_exception_security:
382 * \returns a new instance of the \c System.Security.SecurityException
385 mono_get_exception_security (void)
387 return mono_exception_from_name (mono_get_corlib (), "System.Security",
388 "SecurityException");
392 * mono_exception_new_thread_abort:
393 * \returns a new instance of the \c System.Threading.ThreadAbortException
396 mono_exception_new_thread_abort (MonoError
*error
)
398 return mono_exception_new_by_name (mono_get_corlib (), "System.Threading", "ThreadAbortException", error
);
402 * mono_get_exception_thread_abort:
403 * \returns a new instance of the \c System.Threading.ThreadAbortException
406 mono_get_exception_thread_abort (void)
408 return mono_exception_from_name (mono_get_corlib (), "System.Threading",
409 "ThreadAbortException");
413 * mono_exception_new_thread_interrupted:
414 * \returns a new instance of the \c System.Threading.ThreadInterruptedException
417 mono_exception_new_thread_interrupted (MonoError
*error
)
419 return mono_exception_new_by_name (mono_get_corlib (), "System.Threading", "ThreadInterruptedException", error
);
423 * mono_get_exception_thread_interrupted:
424 * \returns a new instance of the \c System.Threading.ThreadInterruptedException
427 mono_get_exception_thread_interrupted (void)
429 return mono_exception_from_name (mono_get_corlib (), "System.Threading",
430 "ThreadInterruptedException");
434 * mono_get_exception_arithmetic:
435 * \returns a new instance of the \c System.ArithmeticException
438 mono_get_exception_arithmetic (void)
440 return mono_exception_from_name (mono_get_corlib (), "System",
441 "ArithmeticException");
445 * mono_get_exception_overflow:
446 * \returns a new instance of the \c System.OverflowException
449 mono_get_exception_overflow (void)
451 return mono_exception_from_name (mono_get_corlib (), "System",
452 "OverflowException");
456 * mono_get_exception_null_reference:
457 * \returns a new instance of the \c System.NullReferenceException
460 mono_get_exception_null_reference (void)
462 return mono_exception_from_name (mono_get_corlib (), "System",
463 "NullReferenceException");
467 * mono_get_exception_execution_engine:
468 * \param msg the message to pass to the user
469 * \returns a new instance of the \c System.ExecutionEngineException
472 mono_get_exception_execution_engine (const char *msg
)
474 MonoException
*result
;
475 MONO_ENTER_GC_UNSAFE
;
476 result
= mono_exception_from_name_msg (mono_get_corlib (), "System", "ExecutionEngineException", msg
);
482 * mono_get_exception_serialization:
483 * \param msg the message to pass to the user
484 * \returns a new instance of the \c System.Runtime.Serialization.SerializationException
487 mono_get_exception_serialization (const char *msg
)
489 return mono_exception_from_name_msg (mono_get_corlib (), "System.Runtime.Serialization", "SerializationException", msg
);
493 * mono_get_exception_invalid_cast:
494 * \returns a new instance of the \c System.InvalidCastException
497 mono_get_exception_invalid_cast ()
499 return mono_exception_from_name (mono_get_corlib (), "System", "InvalidCastException");
503 * mono_get_exception_invalid_operation:
504 * \param msg the message to pass to the user
505 * \returns a new instance of the \c System.InvalidOperationException
508 mono_get_exception_invalid_operation (const char *msg
)
510 return mono_exception_from_name_msg (mono_get_corlib (), "System",
511 "InvalidOperationException", msg
);
515 mono_exception_new_invalid_operation (const char *msg
, MonoError
*error
)
517 return mono_exception_new_by_name_msg (mono_get_corlib (), "System",
518 "InvalidOperationException", msg
, error
);
522 * mono_get_exception_index_out_of_range:
523 * \returns a new instance of the \c System.IndexOutOfRangeException
526 mono_get_exception_index_out_of_range ()
528 return mono_exception_from_name (mono_get_corlib (), "System",
529 "IndexOutOfRangeException");
533 * mono_get_exception_array_type_mismatch:
534 * \returns a new instance of the \c System.ArrayTypeMismatchException
537 mono_get_exception_array_type_mismatch (void)
539 return mono_exception_from_name (mono_get_corlib (), "System",
540 "ArrayTypeMismatchException");
544 * mono_get_exception_type_load:
545 * \param class_name the name of the class that could not be loaded
546 * \param assembly_name the assembly where the class was looked up.
547 * \returns a new instance of the \c System.TypeLoadException
550 mono_get_exception_type_load (MonoString
*class_name_raw
, char *assembly_name
)
553 HANDLE_FUNCTION_ENTER ();
554 MONO_HANDLE_DCL (MonoString
, class_name
);
555 MonoStringHandle s
= NULL_HANDLE_STRING
;
556 MonoDomain
* const domain
= mono_domain_get ();
558 s
= mono_string_new_handle (domain
, assembly_name
, error
);
559 mono_error_assert_ok (error
);
561 s
= mono_string_empty_handle (domain
);
563 MonoExceptionHandle ret
= mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System",
564 "TypeLoadException", class_name
, s
, error
);
565 mono_error_assert_ok (error
);
566 HANDLE_FUNCTION_RETURN_OBJ (ret
);
570 * mono_get_exception_not_implemented:
571 * \param msg the message to pass to the user
572 * \returns a new instance of the \c System.NotImplementedException
575 mono_get_exception_not_implemented (const char *msg
)
577 return mono_exception_from_name_msg (mono_get_corlib (), "System", "NotImplementedException", msg
);
581 * mono_get_exception_not_supported:
582 * \param msg the message to pass to the user
583 * \returns a new instance of the \c System.NotSupportedException
586 mono_get_exception_not_supported (const char *msg
)
588 return mono_exception_from_name_msg (mono_get_corlib (), "System", "NotSupportedException", msg
);
592 * mono_get_exception_missing_member:
593 * \param exception_type the specific exception type for the specific member type, i.e. field or method
594 * \param class_name the class where the lookup was performed.
595 * \param member_name the name of the missing method.
596 * \returns a new instance of the \c exception_type (MissingFieldException or MissingMethodException)
598 static MonoException
*
599 mono_get_exception_missing_member (const char *exception_type
, const char *class_name
, const char *member_name
)
601 HANDLE_FUNCTION_ENTER ();
603 MonoDomain
* const domain
= mono_domain_get ();
604 MonoStringHandle s1
= mono_string_new_handle (domain
, class_name
, error
);
605 mono_error_assert_ok (error
);
606 MonoStringHandle s2
= mono_string_new_handle (domain
, member_name
, error
);
607 mono_error_assert_ok (error
);
609 MonoExceptionHandle ret
= mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System",
610 exception_type
, s1
, s2
, error
);
611 mono_error_assert_ok (error
);
612 HANDLE_FUNCTION_RETURN_OBJ (ret
);
616 * mono_get_exception_missing_method:
617 * \param class_name the class where the lookup was performed.
618 * \param member_name the name of the missing method.
619 * \returns a new instance of the \c System.MissingMethodException
622 mono_get_exception_missing_method (const char *class_name
, const char *member_name
)
624 return mono_get_exception_missing_member ("MissingMethodException", class_name
, member_name
);
628 * mono_get_exception_missing_field:
629 * \param class_name the class where the lookup was performed
630 * \param member_name the name of the missing field.
631 * \returns a new instance of the \c System.MissingFieldException
634 mono_get_exception_missing_field (const char *class_name
, const char *member_name
)
636 return mono_get_exception_missing_member ("MissingFieldException", class_name
, member_name
);
640 * mono_get_exception_argument_internal:
641 * \param type the actual type
642 * \param arg the name of the argument that is invalid or null, etc.
643 * \param msg optional message
644 * \returns a new instance of the \c System.ArgumentException or derived
646 static MonoException
*
647 mono_get_exception_argument_internal (const char *type
, const char *arg
, const char *msg
)
649 HANDLE_FUNCTION_ENTER ();
651 MonoExceptionHandle ex
= mono_exception_new_argument_internal (type
, arg
, msg
, error
);
652 mono_error_cleanup (error
);
653 HANDLE_FUNCTION_RETURN_OBJ (ex
);
657 * mono_get_exception_argument_null:
658 * \param arg the name of the argument that is null
659 * \returns a new instance of the \c System.ArgumentNullException
662 mono_get_exception_argument_null (const char *arg
)
665 MONO_ENTER_GC_UNSAFE
;
666 ex
= mono_get_exception_argument_internal ("ArgumentNullException", arg
, NULL
);
672 * mono_get_exception_argument:
673 * \param arg the name of the invalid argument.
674 * \returns a new instance of the \c System.ArgumentException
677 mono_get_exception_argument (const char *arg
, const char *msg
)
679 return mono_get_exception_argument_internal ("ArgumentException", arg
, msg
);
682 #ifndef ENABLE_NETCORE
683 TYPED_HANDLE_DECL (MonoArgumentException
);
686 static MonoExceptionHandle
687 mono_exception_new_argument_internal (const char *type
, const char *arg
, const char *msg
, MonoError
*error
)
689 #ifdef ENABLE_NETCORE
690 MonoStringHandle arg_str
= arg
? mono_string_new_handle (mono_domain_get (), arg
, error
) : NULL_HANDLE_STRING
;
691 MonoStringHandle msg_str
= msg
? mono_string_new_handle (mono_domain_get (), msg
, error
) : NULL_HANDLE_STRING
;
693 if (!strcmp (type
, "ArgumentException"))
694 return mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System", type
, msg_str
, arg_str
, error
);
696 return mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System", type
, arg_str
, msg_str
, error
);
698 MonoExceptionHandle ex
= mono_exception_new_by_name_msg (mono_get_corlib (), "System", type
, msg
, error
);
700 if (arg
&& !MONO_HANDLE_IS_NULL (ex
)) {
701 MonoArgumentExceptionHandle argex
= MONO_HANDLE_CAST (MonoArgumentException
, ex
);
702 MonoStringHandle arg_str
= mono_string_new_handle (MONO_HANDLE_DOMAIN (ex
), arg
, error
);
703 MONO_HANDLE_SET (argex
, param_name
, arg_str
);
710 mono_exception_new_argument (const char *arg
, const char *msg
, MonoError
*error
)
712 return mono_exception_new_argument_internal ("ArgumentException", arg
, msg
, error
);
716 mono_exception_new_argument_null (const char *arg
, MonoError
*error
)
718 return mono_exception_new_argument_internal ("ArgumentNullException", arg
, NULL
, error
);
722 mono_exception_new_argument_out_of_range(const char *arg
, const char *msg
, MonoError
*error
)
724 return mono_exception_new_argument_internal ("ArgumentOutOfRangeException", arg
, msg
, error
);
728 mono_exception_new_serialization (const char *msg
, MonoError
*error
)
730 return mono_exception_new_by_name_msg (mono_get_corlib (),
731 "System.Runtime.Serialization", "SerializationException",
732 "Could not serialize unhandled exception.", error
);
736 * mono_get_exception_argument_out_of_range:
737 * \param arg the name of the out of range argument.
738 * \returns a new instance of the \c System.ArgumentOutOfRangeException
741 mono_get_exception_argument_out_of_range (const char *arg
)
743 return mono_get_exception_argument_internal ("ArgumentOutOfRangeException", arg
, NULL
);
747 * mono_get_exception_thread_state:
748 * \param msg the message to present to the user
749 * \returns a new instance of the \c System.Threading.ThreadStateException
752 mono_get_exception_thread_state (const char *msg
)
754 return mono_exception_from_name_msg (
755 mono_get_corlib (), "System.Threading", "ThreadStateException", msg
);
759 * mono_get_exception_io:
760 * \param msg the message to present to the user
761 * \returns a new instance of the \c System.IO.IOException
764 mono_get_exception_io (const char *msg
)
766 return mono_exception_from_name_msg (
767 mono_get_corlib (), "System.IO", "IOException", msg
);
771 * mono_get_exception_file_not_found:
772 * \param fname the name of the file not found.
773 * \returns a new instance of the \c System.IO.FileNotFoundException
776 mono_get_exception_file_not_found (MonoString
*fname_raw
)
778 HANDLE_FUNCTION_ENTER ();
780 MONO_HANDLE_DCL (MonoString
, fname
);
781 MonoExceptionHandle ret
= mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System.IO", "FileNotFoundException", fname
, fname
, error
);
782 mono_error_assert_ok (error
);
783 HANDLE_FUNCTION_RETURN_OBJ (ret
);
787 * mono_get_exception_file_not_found2:
788 * \param msg an informative message for the user.
789 * \param fname the name of the file not found.
790 * \returns a new instance of the \c System.IO.FileNotFoundException
793 mono_get_exception_file_not_found2 (const char *msg
, MonoString
*fname_raw
)
795 HANDLE_FUNCTION_ENTER ();
797 MONO_HANDLE_DCL (MonoString
, fname
);
798 MonoStringHandle s
= NULL_HANDLE_STRING
;
800 s
= mono_string_new_handle (mono_domain_get (), msg
, error
);
801 mono_error_assert_ok (error
);
803 MonoExceptionHandle ret
= mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System.IO", "FileNotFoundException", s
, fname
, error
);
804 mono_error_assert_ok (error
);
805 HANDLE_FUNCTION_RETURN_OBJ (ret
);
809 * mono_get_exception_type_initialization:
810 * \param type_name the name of the type that failed to initialize.
811 * \param inner the inner exception.
812 * \returns a new instance of the \c System.TypeInitializationException
815 mono_get_exception_type_initialization (const gchar
*type_name
, MonoException
* inner_raw
)
817 HANDLE_FUNCTION_ENTER ();
818 MONO_HANDLE_DCL (MonoException
, inner
);
820 MonoExceptionHandle ret
= mono_get_exception_type_initialization_handle (type_name
, inner
, error
);
821 if (!is_ok (error
)) {
822 ret
= MONO_HANDLE_CAST (MonoException
, mono_new_null ());
823 mono_error_cleanup (error
);
825 HANDLE_FUNCTION_RETURN_OBJ (ret
);
829 mono_get_exception_type_initialization_handle (const gchar
*type_name
, MonoExceptionHandle inner
, MonoError
*error
)
831 HANDLE_FUNCTION_ENTER ();
839 klass
= mono_class_load_from_name (mono_get_corlib (), "System", "TypeInitializationException");
841 mono_class_init_internal (klass
);
844 while ((method
= mono_class_get_methods (klass
, &iter
))) {
845 if (!strcmp (".ctor", mono_method_get_name (method
))) {
846 MonoMethodSignature
*sig
= mono_method_signature_internal (method
);
848 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
)
855 MonoDomain
* const domain
= mono_domain_get ();
856 MonoStringHandle type_name_str
= mono_string_new_handle (domain
, type_name
, error
);
857 mono_error_assert_ok (error
);
858 gpointer args
[ ] = { MONO_HANDLE_RAW (type_name_str
), MONO_HANDLE_RAW (inner
) };
860 MonoObjectHandle exc
= mono_object_new_handle (domain
, klass
, error
);
861 mono_error_assert_ok (error
);
863 mono_runtime_invoke_handle_void (method
, exc
, args
, error
);
864 goto_if_nok (error
, return_null
);
867 exc
= mono_new_null ();
869 HANDLE_FUNCTION_RETURN_REF (MonoException
, MONO_HANDLE_CAST (MonoException
, exc
));
873 * mono_get_exception_synchronization_lock:
874 * \param inner the inner exception.
875 * \returns a new instance of the \c System.SynchronizationLockException
878 mono_get_exception_synchronization_lock (const char *msg
)
880 return mono_exception_from_name_msg (mono_get_corlib (), "System.Threading", "SynchronizationLockException", msg
);
884 * mono_get_exception_cannot_unload_appdomain:
885 * \param inner the inner exception.
886 * \returns a new instance of the \c System.CannotUnloadAppDomainException
889 mono_get_exception_cannot_unload_appdomain (const char *msg
)
891 return mono_exception_from_name_msg (mono_get_corlib (), "System", "CannotUnloadAppDomainException", msg
);
895 * mono_get_exception_appdomain_unloaded
896 * \returns a new instance of the \c System.AppDomainUnloadedException
899 mono_get_exception_appdomain_unloaded (void)
901 return mono_exception_from_name (mono_get_corlib (), "System", "AppDomainUnloadedException");
905 * mono_get_exception_bad_image_format:
906 * \param msg an informative message for the user.
907 * \returns a new instance of the \c System.BadImageFormatException
910 mono_get_exception_bad_image_format (const char *msg
)
912 return mono_exception_from_name_msg (mono_get_corlib (), "System", "BadImageFormatException", msg
);
916 * mono_get_exception_bad_image_format2:
917 * \param msg an informative message for the user.
918 * \param fname The full name of the file with the invalid image.
919 * \returns a new instance of the \c System.BadImageFormatException
922 mono_get_exception_bad_image_format2 (const char *msg
, MonoString
*fname_raw
)
924 HANDLE_FUNCTION_ENTER ();
926 MonoStringHandle s
= NULL_HANDLE_STRING
;
927 MONO_HANDLE_DCL (MonoString
, fname
);
930 s
= mono_string_new_handle (mono_domain_get (), msg
, error
);
931 mono_error_assert_ok (error
);
934 MonoExceptionHandle ret
= mono_exception_from_name_two_strings_checked (
935 mono_get_corlib (), "System", "BadImageFormatException", s
, fname
, error
);
936 mono_error_assert_ok (error
);
937 HANDLE_FUNCTION_RETURN_OBJ (ret
);
941 * mono_get_exception_stack_overflow:
942 * \returns a new instance of the \c System.StackOverflowException
945 mono_get_exception_stack_overflow (void)
947 return mono_exception_from_name (mono_get_corlib (), "System", "StackOverflowException");
951 * mono_get_exception_out_of_memory:
952 * \returns a new instance of the \c System.OutOfMemoryException
955 mono_get_exception_out_of_memory (void)
957 return mono_exception_from_name (mono_get_corlib (), "System", "OutOfMemoryException");
961 mono_get_exception_out_of_memory_handle (void)
963 return MONO_HANDLE_NEW (MonoException
, mono_exception_from_name (mono_get_corlib (), "System", "OutOfMemoryException"));
967 * mono_get_exception_field_access:
968 * \returns a new instance of the \c System.FieldAccessException
971 mono_get_exception_field_access (void)
973 return mono_exception_from_name (mono_get_corlib (), "System", "FieldAccessException");
977 * mono_get_exception_field_access2:
978 * \param msg an informative message for the user.
979 * \returns a new instance of the \c System.FieldAccessException
982 mono_get_exception_field_access_msg (const char *msg
)
984 return mono_exception_from_name_msg (mono_get_corlib (), "System", "FieldAccessException", msg
);
988 * mono_get_exception_method_access:
989 * \returns a new instance of the \c System.MethodAccessException
992 mono_get_exception_method_access (void)
994 return mono_exception_from_name (mono_get_corlib (), "System", "MethodAccessException");
998 * mono_get_exception_method_access2:
999 * \param msg an informative message for the user.
1000 * \returns a new instance of the \c System.MethodAccessException
1003 mono_get_exception_method_access_msg (const char *msg
)
1005 return mono_exception_from_name_msg (mono_get_corlib (), "System", "MethodAccessException", msg
);
1009 * mono_get_exception_reflection_type_load:
1010 * \param types an array of types that were defined in the moduled loaded.
1011 * \param exceptions an array of exceptions that were thrown during the type loading.
1012 * \returns a new instance of the \c System.Reflection.ReflectionTypeLoadException
1015 mono_get_exception_reflection_type_load (MonoArray
*types_raw
, MonoArray
*exceptions_raw
)
1017 HANDLE_FUNCTION_ENTER ();
1019 MONO_HANDLE_DCL (MonoArray
, types
);
1020 MONO_HANDLE_DCL (MonoArray
, exceptions
);
1021 MonoExceptionHandle ret
= mono_get_exception_reflection_type_load_checked (types
, exceptions
, error
);
1023 ret
= MONO_HANDLE_CAST (MonoException
, mono_new_null ());
1024 mono_error_cleanup (error
);
1025 HANDLE_FUNCTION_RETURN_OBJ (ret
);
1029 mono_get_exception_reflection_type_load_checked (MonoArrayHandle types
, MonoArrayHandle exceptions
, MonoError
*error
)
1031 HANDLE_FUNCTION_ENTER ();
1039 klass
= mono_class_load_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException");
1041 mono_class_init_internal (klass
);
1043 /* Find the Type[], Exception[] ctor */
1045 while ((method
= mono_class_get_methods (klass
, &iter
))) {
1046 if (!strcmp (".ctor", mono_method_get_name (method
))) {
1047 MonoMethodSignature
*sig
= mono_method_signature_internal (method
);
1049 if (sig
->param_count
== 2 && sig
->params
[0]->type
== MONO_TYPE_SZARRAY
&& sig
->params
[1]->type
== MONO_TYPE_SZARRAY
)
1056 MonoExceptionHandle exc
= MONO_HANDLE_CAST (MonoException
, MONO_HANDLE_NEW (MonoObject
, mono_object_new_checked (mono_domain_get (), klass
, error
)));
1057 mono_error_assert_ok (error
);
1059 gpointer args
[ ] = { MONO_HANDLE_RAW (types
), MONO_HANDLE_RAW (exceptions
) };
1061 mono_runtime_invoke_checked (method
, MONO_HANDLE_RAW (exc
), args
, error
);
1062 goto_if_nok (error
, return_null
);
1065 exc
= MONO_HANDLE_CAST (MonoException
, mono_new_null ());
1067 HANDLE_FUNCTION_RETURN_REF (MonoException
, exc
);
1071 * mono_get_exception_runtime_wrapped:
1074 mono_get_exception_runtime_wrapped (MonoObject
*wrapped_exception_raw
)
1076 HANDLE_FUNCTION_ENTER ();
1078 MONO_HANDLE_DCL (MonoObject
, wrapped_exception
);
1079 MonoExceptionHandle ret
= mono_get_exception_runtime_wrapped_handle (wrapped_exception
, error
);
1080 if (!is_ok (error
)) {
1081 mono_error_cleanup (error
);
1082 ret
= MONO_HANDLE_CAST (MonoException
, mono_new_null ());
1084 HANDLE_FUNCTION_RETURN_OBJ (ret
);
1088 mono_get_exception_runtime_wrapped_handle (MonoObjectHandle wrapped_exception
, MonoError
*error
)
1090 HANDLE_FUNCTION_ENTER ();
1095 klass
= mono_class_load_from_name (mono_get_corlib (), "System.Runtime.CompilerServices", "RuntimeWrappedException");
1097 MonoObjectHandle o
= mono_object_new_handle (mono_domain_get (), klass
, error
);
1098 mono_error_assert_ok (error
);
1099 g_assert (!MONO_HANDLE_IS_NULL (o
));
1101 method
= mono_class_get_method_from_name_checked (klass
, ".ctor", 1, 0, error
);
1102 mono_error_assert_ok (error
);
1105 gpointer args
[ ] = { MONO_HANDLE_RAW (wrapped_exception
) };
1107 mono_runtime_invoke_handle_void (method
, o
, args
, error
);
1108 goto_if_nok (error
, return_null
);
1111 o
= mono_new_null ();
1113 HANDLE_FUNCTION_RETURN_REF (MonoException
, MONO_HANDLE_CAST (MonoException
, o
));
1117 append_frame_and_continue (MonoMethod
*method
, gpointer ip
, size_t native_offset
, gboolean managed
, gpointer user_data
)
1119 MONO_ENTER_GC_UNSAFE
;
1120 MonoDomain
*domain
= mono_domain_get ();
1121 GString
*text
= (GString
*)user_data
;
1124 char *msg
= mono_debug_print_stack_frame (method
, native_offset
, domain
);
1125 g_string_append_printf (text
, "%s\n", msg
);
1128 g_string_append_printf (text
, "<unknown native frame 0x%p>\n", ip
);
1130 MONO_EXIT_GC_UNSAFE
;
1135 mono_exception_get_managed_backtrace (MonoException
*exc
)
1139 text
= g_string_new_len (NULL
, 20);
1141 if (!mono_get_eh_callbacks ()->mono_exception_walk_trace (exc
, append_frame_and_continue
, text
))
1142 g_string_append (text
, "managed backtrace not available\n");
1144 return g_string_free (text
, FALSE
);
1148 mono_exception_handle_get_native_backtrace (MonoExceptionHandle exc
)
1150 #ifdef HAVE_BACKTRACE_SYMBOLS
1152 MonoArrayHandle arr
= MONO_HANDLE_NEW(MonoArray
, NULL
);
1157 MONO_HANDLE_GET (arr
, exc
, native_trace_ips
);
1159 if (MONO_HANDLE_IS_NULL(arr
))
1160 return g_strdup ("");
1161 domain
= mono_domain_get ();
1162 len
= mono_array_handle_length (arr
);
1163 text
= g_string_new_len (NULL
, len
* 20);
1165 gpointer
*addr
= MONO_ARRAY_HANDLE_PIN (arr
, gpointer
, 0, &gchandle
);
1167 messages
= backtrace_symbols (addr
, len
);
1169 mono_gchandle_free_internal (gchandle
);
1171 for (i
= 0; i
< len
; ++i
) {
1173 MONO_HANDLE_ARRAY_GETVAL (ip
, arr
, gpointer
, i
);
1174 MonoJitInfo
*ji
= mono_jit_info_table_find (domain
, ip
);
1176 char *msg
= mono_debug_print_stack_frame (mono_jit_info_get_method (ji
), (char*)ip
- (char*)ji
->code_start
, domain
);
1177 g_string_append_printf (text
, "%s\n", msg
);
1180 g_string_append_printf (text
, "%s\n", messages
[i
]);
1185 return g_string_free (text
, FALSE
);
1187 return g_strdup ("");
1192 ves_icall_Mono_Runtime_GetNativeStackTrace (MonoExceptionHandle exc
, MonoError
*error
)
1195 MonoStringHandle res
;
1198 if (MONO_HANDLE_IS_NULL (exc
)) {
1199 mono_error_set_argument_null (error
, "exception", "");
1200 return NULL_HANDLE_STRING
;
1203 trace
= mono_exception_handle_get_native_backtrace (exc
);
1204 res
= mono_string_new_handle (mono_domain_get (), trace
, error
);
1210 * mono_error_raise_exception_deprecated:
1211 * \param target_error the exception to raise
1213 * Raises the exception of \p target_error.
1214 * Does nothing if \p target_error has a success error code.
1215 * Aborts in case of a double fault. This happens when it can't recover from an error caused by trying
1216 * to construct the first exception object.
1217 * The error object \p target_error is cleaned up.
1220 mono_error_raise_exception_deprecated (MonoError
*target_error
)
1222 MonoException
*ex
= mono_error_convert_to_exception (target_error
);
1224 mono_raise_exception_deprecated (ex
);
1228 * mono_error_set_pending_exception_slow:
1229 * \param error The error
1230 * If \p error is set, convert it to an exception and set the pending exception for the current icall.
1231 * \returns TRUE if \p error was set, or FALSE otherwise, so that you can write:
1232 * if (mono_error_set_pending_exception (error)) {
1233 * { ... cleanup code ... }
1237 // For efficiency, call mono_error_set_pending_exception instead of mono_error_set_pending_exception_slow.
1239 mono_error_set_pending_exception_slow (MonoError
*error
)
1244 HANDLE_FUNCTION_ENTER ();
1246 MonoExceptionHandle ex
= mono_error_convert_to_exception_handle (error
);
1247 gboolean
const result
= !MONO_HANDLE_IS_NULL (ex
);
1249 mono_set_pending_exception_handle (ex
);
1251 HANDLE_FUNCTION_RETURN_VAL (result
);
1255 mono_install_unhandled_exception_hook (MonoUnhandledExceptionFunc func
, void *user_data
)
1257 unhandled_exception_hook
= func
;
1258 unhandled_exception_hook_data
= user_data
;
1262 mono_invoke_unhandled_exception_hook (MonoObject
*exc
)
1264 if (unhandled_exception_hook
) {
1265 unhandled_exception_hook (exc
, unhandled_exception_hook_data
);
1267 ERROR_DECL (inner_error
);
1268 MonoObject
*other
= NULL
;
1269 MonoString
*str
= mono_object_try_to_string (exc
, &other
, inner_error
);
1272 if (str
&& is_ok (inner_error
)) {
1273 msg
= mono_string_to_utf8_checked_internal (str
, inner_error
);
1274 if (!is_ok (inner_error
)) {
1275 msg
= g_strdup_printf ("Nested exception while formatting original exception");
1276 mono_error_cleanup (inner_error
);
1279 char *original_backtrace
= mono_exception_get_managed_backtrace ((MonoException
*)exc
);
1280 char *nested_backtrace
= mono_exception_get_managed_backtrace ((MonoException
*)other
);
1282 msg
= g_strdup_printf ("Nested exception detected.\nOriginal Exception: %s\nNested exception:%s\n",
1283 original_backtrace
, nested_backtrace
);
1285 g_free (original_backtrace
);
1286 g_free (nested_backtrace
);
1288 msg
= g_strdup ("Nested exception trying to figure out what went wrong");
1290 mono_runtime_printf_err ("[ERROR] FATAL UNHANDLED EXCEPTION: %s", msg
);
1292 #if defined(HOST_IOS)
1293 g_assertion_message ("Terminating runtime due to unhandled exception");
1295 exit (mono_environment_exitcode_get ());
1299 g_assert_not_reached ();
1303 mono_corlib_exception_new_with_args (const char *name_space
, const char *name
, const char *arg_0
, const char *arg_1
, MonoError
*error
)
1305 HANDLE_FUNCTION_ENTER ();
1307 MonoStringHandle str_0
= NULL_HANDLE_STRING
;
1308 MonoStringHandle str_1
= NULL_HANDLE_STRING
;
1309 MonoExceptionHandle ex
= MONO_HANDLE_CAST (MonoException
, NULL_HANDLE
);
1310 MonoDomain
* const domain
= mono_domain_get ();
1312 str_0
= arg_0
? mono_string_new_handle (domain
, arg_0
, error
) : NULL_HANDLE_STRING
;
1313 goto_if_nok (error
, return_null
);
1315 str_1
= arg_1
? mono_string_new_handle (domain
, arg_1
, error
) : NULL_HANDLE_STRING
;
1316 goto_if_nok (error
, return_null
);
1318 ex
= mono_exception_from_name_two_strings_checked (mono_defaults
.corlib
, name_space
, name
, str_0
, str_1
, error
);
1321 ex
= MONO_HANDLE_CAST (MonoException
, mono_new_null ());
1323 HANDLE_FUNCTION_RETURN_REF (MonoException
, ex
);
1327 mono_error_set_field_missing (MonoError
*error
, MonoClass
*klass
, const char *field_name
, MonoType
*sig
, const char *reason
, ...)
1332 res
= g_string_new ("Field not found: ");
1336 mono_type_get_desc (res
, sig
, TRUE
);
1337 g_string_append_c (res
, ' ');
1341 if (m_class_get_name_space (klass
)) {
1342 g_string_append (res
, m_class_get_name_space (klass
));
1343 g_string_append_c (res
, '.');
1345 g_string_append (res
, m_class_get_name (klass
));
1348 g_string_append (res
, "<unknown type>");
1351 g_string_append_c (res
, '.');
1354 g_string_append (res
, field_name
);
1356 g_string_append (res
, "<unknown field>");
1358 if (reason
&& *reason
) {
1360 va_start (args
, reason
);
1362 g_string_append (res
, " Due to: ");
1363 g_string_append_vprintf (res
, reason
, args
);
1367 g_string_free (res
, FALSE
);
1369 mono_error_set_specific (error
, MONO_ERROR_MISSING_FIELD
, result
);
1373 * Sets @error to a method missing error.
1376 mono_error_set_method_missing (MonoError
*error
, MonoClass
*klass
, const char *method_name
, MonoMethodSignature
*sig
, const char *reason
, ...)
1382 res
= g_string_new ("Method not found: ");
1385 mono_type_get_desc (res
, sig
->ret
, TRUE
);
1387 g_string_append_c (res
, ' ');
1391 if (m_class_get_name_space (klass
)) {
1392 g_string_append (res
, m_class_get_name_space (klass
));
1393 g_string_append_c (res
, '.');
1395 g_string_append (res
, m_class_get_name (klass
));
1398 g_string_append (res
, "<unknown type>");
1401 g_string_append_c (res
, '.');
1404 g_string_append (res
, method_name
);
1406 g_string_append (res
, "<unknown method>");
1409 if (sig
->generic_param_count
) {
1410 g_string_append_c (res
, '<');
1411 for (i
= 0; i
< sig
->generic_param_count
; ++i
) {
1413 g_string_append (res
, ",");
1414 g_string_append_printf (res
, "!%d", i
);
1416 g_string_append_c (res
, '>');
1419 g_string_append_c (res
, '(');
1420 for (i
= 0; i
< sig
->param_count
; ++i
) {
1422 g_string_append_c (res
, ',');
1423 mono_type_get_desc (res
, sig
->params
[i
], TRUE
);
1425 g_string_append_c (res
, ')');
1428 if (reason
&& *reason
) {
1430 va_start (args
, reason
);
1432 g_string_append (res
, " Due to: ");
1433 g_string_append_vprintf (res
, reason
, args
);
1437 g_string_free (res
, FALSE
);
1439 mono_error_set_specific (error
, MONO_ERROR_MISSING_METHOD
, result
);
1442 #define SET_ERROR_MSG(STR_VAR, FMT_STR) do { \
1444 va_start (__args, FMT_STR); \
1445 STR_VAR = g_strdup_vprintf (FMT_STR, __args); \
1450 * \p image_name argument will be g_strdup'd. Called must free passed value
1453 mono_error_set_bad_image_by_name (MonoError
*error
, const char *image_name
, const char *msg_format
, ...)
1456 SET_ERROR_MSG (str
, msg_format
);
1458 mono_error_set_specific (error
, MONO_ERROR_BAD_IMAGE
, str
);
1460 mono_error_set_first_argument (error
, image_name
);
1464 mono_error_set_bad_image (MonoError
*error
, MonoImage
*image
, const char *msg_format
, ...)
1467 SET_ERROR_MSG (str
, msg_format
);
1469 mono_error_set_specific (error
, MONO_ERROR_BAD_IMAGE
, str
);
1471 mono_error_set_first_argument (error
, mono_image_get_name (image
));
1475 mono_error_set_file_not_found (MonoError
*error
, const char *file_name
, const char *msg_format
, ...)
1478 SET_ERROR_MSG (str
, msg_format
);
1480 mono_error_set_specific (error
, MONO_ERROR_FILE_NOT_FOUND
, str
);
1482 mono_error_set_first_argument (error
, file_name
);
1486 mono_error_set_simple_file_not_found (MonoError
*error
, const char *file_name
, gboolean refection_only
)
1489 mono_error_set_file_not_found (error
, file_name
, "Cannot resolve dependency to assembly 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.");
1491 mono_error_set_file_not_found (error
, file_name
, "Could not load file or assembly '%s' or one of its dependencies.", file_name
);
1495 mono_error_set_argument_out_of_range (MonoError
*error
, const char *param_name
, const char *msg_format
, ...)
1498 SET_ERROR_MSG (str
, msg_format
);
1499 mono_error_set_specific (error
, MONO_ERROR_ARGUMENT_OUT_OF_RANGE
, str
);
1501 mono_error_set_first_argument (error
, param_name
);
1505 mono_error_convert_to_exception_handle (MonoError
*error
)
1507 //FIXMEcoop mono_error_convert_to_exception is raw pointer
1508 // The "optimization" here is important to significantly reduce handle usage.
1509 return is_ok (error
) ? MONO_HANDLE_CAST (MonoException
, NULL_HANDLE
)
1510 : MONO_HANDLE_NEW (MonoException
, mono_error_convert_to_exception (error
));