void print_unhandled_exception(MonoObject *p_exc, bool p_recursion_caution) { mono_print_unhandled_exception(p_exc); #ifdef DEBUG_ENABLED if (!ScriptDebugger::get_singleton()) return; ScriptLanguage::StackInfo separator; separator.file = ""; separator.func = "--- " + RTR("End of inner exception stack trace") + " ---"; separator.line = 0; Vector<ScriptLanguage::StackInfo> si; String exc_msg = ""; while (p_exc != NULL) { GDMonoClass *st_klass = CACHED_CLASS(System_Diagnostics_StackTrace); MonoObject *stack_trace = mono_object_new(mono_domain_get(), st_klass->get_mono_ptr()); MonoBoolean need_file_info = true; void *ctor_args[2] = { p_exc, &need_file_info }; MonoObject *unexpected_exc = NULL; CACHED_METHOD(System_Diagnostics_StackTrace, ctor_Exception_bool)->invoke_raw(stack_trace, ctor_args, &unexpected_exc); if (unexpected_exc != NULL) { mono_print_unhandled_exception(unexpected_exc); if (p_recursion_caution) { // Called from CSharpLanguage::get_current_stack_info, // so printing an error here could result in endless recursion OS::get_singleton()->printerr("Mono: Method GDMonoUtils::print_unhandled_exception failed"); return; } else { ERR_FAIL(); } } Vector<ScriptLanguage::StackInfo> _si; if (stack_trace != NULL && !p_recursion_caution) { _si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace); for (int i = _si.size() - 1; i >= 0; i--) si.insert(0, _si[i]); } exc_msg += (exc_msg.length() > 0 ? " ---> " : "") + GDMonoUtils::get_exception_name_and_message(p_exc); GDMonoProperty *p_prop = GDMono::get_singleton()->get_class(mono_object_get_class(p_exc))->get_property("InnerException"); p_exc = p_prop != NULL ? p_prop->get_value(p_exc) : NULL; if (p_exc != NULL) si.insert(0, separator); } String file = si.size() ? si[0].file : __FILE__; String func = si.size() ? si[0].func : FUNCTION_STR; int line = si.size() ? si[0].line : __LINE__; String error_msg = "Unhandled exception"; ScriptDebugger::get_singleton()->send_error(func, file, line, error_msg, exc_msg, ERR_HANDLER_ERROR, si); #endif }
Dictionary mono_object_to_Dictionary(MonoObject *p_dict) { Dictionary ret; GDMonoUtils::MarshalUtils_DictToArrays dict_to_arrays = CACHED_METHOD_THUNK(MarshalUtils, DictionaryToArrays); MonoArray *keys = NULL; MonoArray *values = NULL; MonoObject *ex = NULL; dict_to_arrays(p_dict, &keys, &values, &ex); if (ex) { mono_print_unhandled_exception(ex); ERR_FAIL_V(Dictionary()); } int length = mono_array_length(keys); for (int i = 0; i < length; i++) { MonoObject *key_obj = mono_array_get(keys, MonoObject *, i); MonoObject *value_obj = mono_array_get(values, MonoObject *, i); Variant key = key_obj ? mono_object_to_variant(key_obj) : Variant(); Variant value = value_obj ? mono_object_to_variant(value_obj) : Variant(); ret[key] = value; } return ret; }
void print_unhandled_exception(MonoObject *p_exc, bool p_recursion_caution) { mono_print_unhandled_exception(p_exc); #ifdef DEBUG_ENABLED if (!ScriptDebugger::get_singleton()) return; GDMonoClass *st_klass = CACHED_CLASS(System_Diagnostics_StackTrace); MonoObject *stack_trace = mono_object_new(mono_domain_get(), st_klass->get_mono_ptr()); MonoBoolean need_file_info = true; void *ctor_args[2] = { p_exc, &need_file_info }; MonoObject *unexpected_exc = NULL; CACHED_METHOD(System_Diagnostics_StackTrace, ctor_Exception_bool)->invoke_raw(stack_trace, ctor_args, &unexpected_exc); if (unexpected_exc != NULL) { mono_print_unhandled_exception(unexpected_exc); if (p_recursion_caution) { // Called from CSharpLanguage::get_current_stack_info, // so printing an error here could result in endless recursion OS::get_singleton()->printerr("Mono: Method GDMonoUtils::print_unhandled_exception failed"); return; } else { ERR_FAIL(); } } Vector<ScriptLanguage::StackInfo> si; if (stack_trace != NULL && !p_recursion_caution) si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace); String file = si.size() ? si[0].file : __FILE__; String func = si.size() ? si[0].func : FUNCTION_STR; int line = si.size() ? si[0].line : __LINE__; String error_msg = "Unhandled exception"; String exc_msg = GDMonoUtils::get_exception_name_and_message(p_exc); ScriptDebugger::get_singleton()->send_error(func, file, line, error_msg, exc_msg, ERR_HANDLER_ERROR, si); #endif }
Variant SignalAwaiterHandle::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { #ifdef DEBUG_ENABLED if (conn_target_id && !ObjectDB::get_instance(conn_target_id)) { ERR_EXPLAIN("Resumed after await, but class instance is gone"); ERR_FAIL_V(Variant()); } #endif if (p_argcount < 1) { r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; return Variant(); } Ref<SignalAwaiterHandle> self = *p_args[p_argcount - 1]; if (self.is_null()) { r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = p_argcount - 1; r_error.expected = Variant::OBJECT; return Variant(); } set_completed(true); int signal_argc = p_argcount - 1; MonoArray *signal_args = mono_array_new(SCRIPTS_DOMAIN, CACHED_CLASS_RAW(MonoObject), signal_argc); for (int i = 0; i < signal_argc; i++) { MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_args[i]); mono_array_set(signal_args, MonoObject *, i, boxed); } GDMonoUtils::SignalAwaiter_SignalCallback thunk = CACHED_METHOD_THUNK(SignalAwaiter, SignalCallback); MonoObject *ex = NULL; thunk(get_target(), &signal_args, &ex); if (ex) { mono_print_unhandled_exception(ex); ERR_FAIL_V(Variant()); } return Variant(); }
Error GDMono::_unload_scripts_domain() { ERR_FAIL_NULL_V(scripts_domain, ERR_BUG); if (OS::get_singleton()->is_stdout_verbose()) { OS::get_singleton()->print("Mono: Unloading scripts domain...\n"); } _GodotSharp::get_singleton()->_dispose_callback(); if (mono_domain_get() != root_domain) mono_domain_set(root_domain, true); mono_gc_collect(mono_gc_max_generation()); finalizing_scripts_domain = true; mono_domain_finalize(scripts_domain, 2000); finalizing_scripts_domain = false; mono_gc_collect(mono_gc_max_generation()); _domain_assemblies_cleanup(mono_domain_get_id(scripts_domain)); api_assembly = NULL; project_assembly = NULL; #ifdef TOOLS_ENABLED editor_api_assembly = NULL; #endif MonoDomain *domain = scripts_domain; scripts_domain = NULL; _GodotSharp::get_singleton()->_dispose_callback(); MonoObject *ex = NULL; mono_domain_try_unload(domain, &ex); if (ex) { ERR_PRINT("Exception thrown when unloading scripts domain:"); mono_print_unhandled_exception(ex); return FAILED; } return OK; }
SignalAwaiterHandle::~SignalAwaiterHandle() { if (!completed) { GDMonoUtils::SignalAwaiter_FailureCallback thunk = CACHED_METHOD_THUNK(SignalAwaiter, FailureCallback); MonoObject *awaiter = get_target(); if (awaiter) { MonoObject *ex = NULL; thunk(awaiter, &ex); if (ex) { mono_print_unhandled_exception(ex); ERR_FAIL_V(); } } } }
void add_item(const String &p_project_path, const String &p_item_type, const String &p_include) { _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) GDMonoClass *klass = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Project", "ProjectUtils"); Variant project_path = p_project_path; Variant item_type = p_item_type; Variant include = p_include; const Variant *args[3] = { &project_path, &item_type, &include }; MonoObject *ex = NULL; klass->get_method("AddItemToProjectChecked", 3)->invoke(NULL, args, &ex); if (ex) { mono_print_unhandled_exception(ex); ERR_FAIL(); } }
String generate_core_api_project(const String &p_dir, const Vector<String> &p_files) { _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) GDMonoClass *klass = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Project", "ProjectGenerator"); Variant dir = p_dir; Variant compile_items = p_files; const Variant *args[2] = { &dir, &compile_items }; MonoObject *ex = NULL; MonoObject *ret = klass->get_method("GenCoreApiProject", 2)->invoke(NULL, args, &ex); if (ex) { mono_print_unhandled_exception(ex); ERR_FAIL_V(String()); } return ret ? GDMonoMarshal::mono_string_to_godot((MonoString *)ret) : ""; }
MonoObject *Dictionary_to_mono_object(const Dictionary &p_dict) { MonoArray *keys = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_dict.size()); MonoArray *values = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_dict.size()); int i = 0; const Variant *dkey = NULL; while ((dkey = p_dict.next(dkey))) { mono_array_set(keys, MonoObject *, i, variant_to_mono_object(dkey)); mono_array_set(values, MonoObject *, i, variant_to_mono_object(p_dict[*dkey])); i++; } GDMonoUtils::MarshalUtils_ArraysToDict arrays_to_dict = CACHED_METHOD_THUNK(MarshalUtils, ArraysToDictionary); MonoObject *ex = NULL; MonoObject *ret = arrays_to_dict(keys, values, &ex); if (ex) { mono_print_unhandled_exception(ex); ERR_FAIL_V(NULL); } return ret; }
void print_unhandled_exception(MonoException *p_exc) { mono_print_unhandled_exception((MonoObject *)p_exc); }
int main(int argc, char** argv) { std::string app_base; std::string assembly_path; // REVIEW: Not reliable (figure out how to do this in a portable way) if(argc > 0) { assembly_path = argv[0]; app_base = assembly_path.substr(0, assembly_path.length() - 3); assembly_path = app_base + s_managed_assembly_name; } MonoDomain* domain = mono_jit_init ("klr"); if(domain == NULL) { printf("Failed to create mono runtime\n"); return -1; } MonoAssembly* assembly = mono_domain_assembly_open(domain, assembly_path.c_str()); if(assembly == NULL) { printf("Unable to locate klr.mono.managed.dll\n"); return -1; } MonoImage* image = mono_assembly_get_image(assembly); if(image == NULL) { printf("Unable to get mono image for klr.mono.managed.dll\n"); return -1; } MonoClass* klass = mono_class_from_name(image, "", "EntryPoint"); if(image == NULL) { printf("Unable to get class for EntryPoint\n"); return -1; } MonoMethod* method = mono_class_get_method_from_name(klass, "Main", 2); if(method == NULL) { printf("Unable to find Main method\n"); return -1; } MonoObject* exception; void* args[2]; args[0] = &argc; args[1] = argv; mono_runtime_invoke(method, NULL, args, &exception); if(exception != NULL) { mono_print_unhandled_exception(exception); return -1; } return 0; }