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)'.
This commit is contained in:
Ignacio Etcheverry 2017-10-23 00:35:04 +02:00
parent acaaf2e440
commit 45e5e23ee8
3 changed files with 54 additions and 7 deletions

View file

@ -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);

View file

@ -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");
}

View file

@ -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) {