diff options
author | Ignacio Etcheverry <ignalfonsore@gmail.com> | 2017-10-23 00:35:04 +0200 |
---|---|---|
committer | Ignacio Etcheverry <ignalfonsore@gmail.com> | 2017-10-23 00:35:14 +0200 |
commit | 45e5e23ee83d202461f1753b1d94afc51d3a5aa1 (patch) | |
tree | 513bd0522d4207236af464919c342fb3aa163c74 | |
parent | acaaf2e440994bf99b9dcf1ba14ab4a7aa9be854 (diff) |
Mono: Prevent raising exceptions in native code
For now we will just print the exceptions we catch. Later, we should use something similar to 'mono_set_pending_exception(ex)'.
-rw-r--r-- | modules/mono/editor/bindings_generator.cpp | 8 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 12 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_method.cpp | 41 |
3 files changed, 54 insertions, 7 deletions
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 95e75f9103..1d1bcfb03f 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -778,8 +778,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str cs_file.push_back(itype.proxy_name); cs_file.push_back("(IntPtr " BINDINGS_PTR_FIELD ")\n" OPEN_BLOCK_L2 "this." BINDINGS_PTR_FIELD " = " BINDINGS_PTR_FIELD ";\n" CLOSE_BLOCK_L2); - cs_file.push_back(MEMBER_BEGIN "public bool HasValidHandle()\n" OPEN_BLOCK_L2 - "return " BINDINGS_PTR_FIELD " == IntPtr.Zero;\n" CLOSE_BLOCK_L2); + cs_file.push_back(MEMBER_BEGIN "public IntPtr NativeInstance\n" OPEN_BLOCK_L2 + "get { return " BINDINGS_PTR_FIELD "; }\n" CLOSE_BLOCK_L2); } else if (itype.is_singleton) { // Add the type name and the singleton pointer as static fields @@ -841,8 +841,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str // Add methods if (!is_derived_type) { - cs_file.push_back(MEMBER_BEGIN "public bool HasValidHandle()\n" OPEN_BLOCK_L2 - "return " BINDINGS_PTR_FIELD " == IntPtr.Zero;\n" CLOSE_BLOCK_L2); + cs_file.push_back(MEMBER_BEGIN "public IntPtr NativeInstance\n" OPEN_BLOCK_L2 + "get { return " BINDINGS_PTR_FIELD "; }\n" CLOSE_BLOCK_L2); cs_file.push_back(MEMBER_BEGIN "internal static IntPtr " CS_SMETHOD_GETINSTANCE "(Object instance)\n" OPEN_BLOCK_L2 "return instance == null ? IntPtr.Zero : instance." BINDINGS_PTR_FIELD ";\n" CLOSE_BLOCK_L2); diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index d7aedbbcf0..4b5f5eb137 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "gd_mono.h" +#include <mono/metadata/exception.h> #include <mono/metadata/mono-config.h> #include <mono/metadata/mono-debug.h> #include <mono/metadata/mono-gc.h> @@ -47,6 +48,15 @@ #include "../editor/godotsharp_editor.h" #endif +void gdmono_unhandled_exception_hook(MonoObject *exc, void *user_data) { + + (void)user_data; // UNUSED + + ERR_PRINT(GDMonoUtils::get_exception_name_and_message(exc).utf8()); + mono_print_unhandled_exception(exc); + abort(); +} + #ifdef MONO_PRINT_HANDLER_ENABLED void gdmono_MonoPrintCallback(const char *string, mono_bool is_stdout) { @@ -214,6 +224,8 @@ void GDMono::initialize() { // The following assemblies are not required at initialization _load_all_script_assemblies(); + mono_install_unhandled_exception_hook(gdmono_unhandled_exception_hook, NULL); + OS::get_singleton()->print("Mono: ALL IS GOOD\n"); } diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp index 6468e0d3d9..eb97d62900 100644 --- a/modules/mono/mono_gd/gd_mono_method.cpp +++ b/modules/mono/mono_gd/gd_mono_method.cpp @@ -83,9 +83,32 @@ MonoObject *GDMonoMethod::invoke(MonoObject *p_object, const Variant **p_params, mono_array_set(params, MonoObject *, i, boxed_param); } - return mono_runtime_invoke_array(mono_method, p_object, params, r_exc); + MonoObject *exc = NULL; + MonoObject *ret = mono_runtime_invoke_array(mono_method, p_object, params, &exc); + + if (exc) { + if (r_exc) { + *r_exc = exc; + } else { + ERR_PRINT(GDMonoUtils::get_exception_name_and_message(exc).utf8()); + mono_print_unhandled_exception(exc); + } + } + + return ret; } else { - mono_runtime_invoke(mono_method, p_object, NULL, r_exc); + MonoObject *exc = NULL; + mono_runtime_invoke(mono_method, p_object, NULL, &exc); + + if (exc) { + if (r_exc) { + *r_exc = exc; + } else { + ERR_PRINT(GDMonoUtils::get_exception_name_and_message(exc).utf8()); + mono_print_unhandled_exception(exc); + } + } + return NULL; } } @@ -96,7 +119,19 @@ MonoObject *GDMonoMethod::invoke(MonoObject *p_object, MonoObject **r_exc) { } MonoObject *GDMonoMethod::invoke_raw(MonoObject *p_object, void **p_params, MonoObject **r_exc) { - return mono_runtime_invoke(mono_method, p_object, p_params, r_exc); + MonoObject *exc = NULL; + MonoObject *ret = mono_runtime_invoke(mono_method, p_object, p_params, &exc); + + if (exc) { + if (r_exc) { + *r_exc = exc; + } else { + ERR_PRINT(GDMonoUtils::get_exception_name_and_message(exc).utf8()); + mono_print_unhandled_exception(exc); + } + } + + return ret; } bool GDMonoMethod::has_attribute(GDMonoClass *p_attr_class) { |