void debug_send_unhandled_exception_error(MonoException *p_exc) { #ifdef DEBUG_ENABLED if (!ScriptDebugger::get_singleton()) return; _TLS_RECURSION_GUARD_; ScriptLanguage::StackInfo separator; separator.file = String(); 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 }; MonoException *unexpected_exc = NULL; CACHED_METHOD(System_Diagnostics_StackTrace, ctor_Exception_bool)->invoke_raw(stack_trace, ctor_args, &unexpected_exc); if (unexpected_exc) { GDMonoInternals::unhandled_exception(unexpected_exc); _UNREACHABLE_(); } Vector<ScriptLanguage::StackInfo> _si; if (stack_trace != NULL) { _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); GDMonoClass *exc_class = GDMono::get_singleton()->get_class(mono_get_exception_class()); GDMonoProperty *inner_exc_prop = exc_class->get_property("InnerException"); CRASH_COND(inner_exc_prop == NULL); MonoObject *inner_exc = inner_exc_prop->get_value((MonoObject *)p_exc); if (inner_exc != NULL) si.insert(0, separator); p_exc = (MonoException *)inner_exc; } 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 }
CScriptDomain::~CScriptDomain() { m_bDestroying = true; for each(auto assembly in m_assemblies) delete assembly; m_assemblies.clear(); if(m_bRootDomain) mono_jit_cleanup(m_pDomain); else { if(IsActive()) mono_domain_set(mono_get_root_domain(), false); mono_domain_finalize(m_pDomain, 2000); MonoObject *pException; try { mono_domain_try_unload(m_pDomain, &pException); } catch(char *ex) { MonoWarning("An exception was raised during ScriptDomain unload: %s", ex); } if(pException) { MonoWarning("An exception was raised during ScriptDomain unload:"); MonoMethod *pExceptionMethod = mono_method_desc_search_in_class(mono_method_desc_new("::ToString()", false),mono_get_exception_class()); MonoString *exceptionString = (MonoString *)mono_runtime_invoke(pExceptionMethod, pException, nullptr, nullptr); CryLogAlways(ToCryString((mono::string)exceptionString)); } } g_pScriptSystem->OnDomainReleased(this); }
void virt_mono_throw_unhandled_exception (MonoObject *exc) { caddr_t err; char *message = (char *) ""; const char *name = (const char *) ""; MonoString *str; MonoMethod *method; MonoClass *klass; gboolean free_message = FALSE; gint i; if (mono_object_isinst (exc, mono_get_exception_class ())) { klass = mono_object_get_class (exc); method = NULL; while (klass && method == NULL) { gpointer m_iter = NULL; for (method = mono_class_get_methods (klass, &m_iter); method != NULL; method = mono_class_get_methods (klass, &m_iter)) { MonoMethodSignature *sig = mono_method_signature (method); guint32 flags = 0; const char *name = mono_method_get_name (method); mono_method_get_flags (method, &flags); if (!strcmp ("ToString", name) && sig->param_count == 0 #ifdef OLD_KIT_1_1_5 && (flags & METHOD_ATTRIBUTE_VIRTUAL) && (flags & METHOD_ATTRIBUTE_PUBLIC) #endif ) { break; } method = NULL; } if (method == NULL) klass = mono_class_get_parent (klass); } g_assert (method); str = (MonoString *) mono_runtime_invoke (method, exc, NULL, NULL); if (str) { message = mono_string_to_utf8 (str); free_message = TRUE; name = mono_class_get_name (klass); } } /* * g_printerr ("\nUnhandled Exception: %s.%s: %s\n", exc->vtable->klass->name_space, * exc->vtable->klass->name, message); */ g_printerr ("\nUnhandled Exception: %s\n", message); err = srv_make_new_error ("42000", "MN001", "Unhandled Mono Exception [%.200s]: %.200s", name, message); if (free_message) g_free (message); sqlr_resignal (err); }