void gdmono_debug_init() { mono_debug_init(MONO_DEBUG_FORMAT_MONO); int da_port = GLOBAL_DEF("mono/debugger_agent/port", 23685); bool da_suspend = GLOBAL_DEF("mono/debugger_agent/wait_for_debugger", false); int da_timeout = GLOBAL_DEF("mono/debugger_agent/wait_timeout", 3000); #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint() || ProjectSettings::get_singleton()->get_resource_path().empty() || _is_project_manager_requested()) { return; } #endif CharString da_args = String("--debugger-agent=transport=dt_socket,address=127.0.0.1:" + itos(da_port) + ",embedding=1,server=y,suspend=" + (da_suspend ? "y,timeout=" + itos(da_timeout) : "n")) .utf8(); // --debugger-agent=help const char *options[] = { "--soft-breakpoints", da_args.get_data() }; mono_jit_parse_options(2, (char **)options); }
void MonoRuntime::Load(std::string assemblyDir, std::string configDir, std::string traceLevel, std::string file) { if (isLoaded_) { return; } if (!assemblyDir.empty() && !configDir.empty()) { mono_set_dirs(assemblyDir.c_str(), configDir.c_str()); } #ifdef _WIN32 else { mono_set_dirs(PathUtil::GetLibDirectory().c_str(), PathUtil::GetConfigDirectory().c_str()); } #endif mono_debug_init(MONO_DEBUG_FORMAT_MONO); mono_trace_set_level_string(traceLevel.c_str()); MonoDomain *dom = mono_jit_init(file.c_str()); isLoaded_ = true; }
CScriptSystem::CScriptSystem(IGameFramework *pGameFramework) : m_pRootDomain(nullptr) , m_pCryBraryAssembly(nullptr) , m_pPdb2MdbAssembly(nullptr) , m_pScriptManager(nullptr) , m_pScriptDomain(nullptr) , m_bReloading(false) , m_bDetectedChanges(false) , m_bQuitting(false) , m_pConverter(nullptr) , m_bFirstReload(true) , m_pGameFramework(pGameFramework) { CryLogAlways("Initializing Mono Script System"); g_pThis = this; m_pCVars = new SCVars(); g_pMonoCVars = m_pCVars; // We should look into storing mono binaries, configuration as well as scripts via CryPak. mono_set_dirs(PathUtils::GetMonoLibPath(), PathUtils::GetMonoConfigPath()); #ifndef _RELEASE // Enable Mono signal handling // Makes sure that Mono sends back exceptions it tries to handle, for CE crash handling. mono_set_signal_chaining(true); #endif string monoCmdOptions = ""; if(auto *pArg = gEnv->pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "monoArgs")) monoCmdOptions.append(pArg->GetValue()); // Commandline switch -DEBUG makes the process connect to the debugging server. Warning: Failure to connect to a debugging server WILL result in a crash. // This is currently a WIP feature which requires custom MonoDevelop extensions and other irritating things. const ICmdLineArg* arg = gEnv->pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "DEBUG"); if (arg != nullptr) monoCmdOptions.append("--debugger-agent=transport=dt_socket,address=127.0.0.1:65432,embedding=1"); #ifndef _RELEASE else if(g_pMonoCVars->mono_softBreakpoints) // Soft breakpoints not compatible with debugging server { CryLogAlways(" [Performance Warning] Mono soft breakpoints are enabled!"); // Prevents managed null reference exceptions causing crashes in unmanaged code // See: https://bugzilla.xamarin.com/show_bug.cgi?id=5963 monoCmdOptions.append("--soft-breakpoints"); } #endif char *options = new char[monoCmdOptions.size() + 1]; strcpy(options, monoCmdOptions.c_str()); // Note: iPhone requires AOT compilation, this can be enforced via mono options. TODO: Get Crytek to add CryMobile support to the Free SDK. mono_jit_parse_options(1, &options); #ifndef _RELEASE // Required for mdb's to load for detailed stack traces etc. mono_debug_init(MONO_DEBUG_FORMAT_MONO); #endif m_pConverter = new CConverter(); if(!CompleteInit()) { CryLogAlways("CryMono initialization failed!"); return; } RegisterSecondaryBindings(); pGameFramework->RegisterListener(this, "CryMono", FRAMEWORKLISTENERPRIORITY_GAME); gEnv->pSystem->GetISystemEventDispatcher()->RegisterListener(&g_systemEventListener_CryMono); if(IFileChangeMonitor *pFileChangeMonitor = gEnv->pFileChangeMonitor) pFileChangeMonitor->RegisterListener(this, "scripts\\"); CryModuleMemoryInfo memInfo; CryModuleGetMemoryInfo(&memInfo); IMonoClass *pCryStats = m_pCryBraryAssembly->GetClass("CryStats", "CryEngine.Utilities"); IMonoObject *pMemoryUsage = *pCryStats->GetPropertyValue(NULL, "MemoryUsage"); CryLogAlways(" Initializing CryMono done, MemUsage=%iKb", (memInfo.allocated + pMemoryUsage->Unbox<long>()) / 1024); pMemoryUsage->Release(); }
CScriptSystem::CScriptSystem() : m_pRootDomain(nullptr) , m_pCryBraryAssembly(nullptr) , m_pPdb2MdbAssembly(nullptr) , m_pScriptManager(nullptr) , m_pScriptDomain(nullptr) , m_bReloading(false) , m_bDetectedChanges(false) , m_bQuitting(false) , m_pConverter(nullptr) { CryLogAlways("Initializing Mono Script System"); #ifndef PLUGIN_SDK gEnv->pMonoScriptSystem = this; #endif; g_pScriptSystem = this; m_pCVars = new SCVars(); g_pMonoCVars = m_pCVars; // We should look into storing mono binaries, configuration as well as scripts via CryPak. mono_set_dirs(PathUtils::GetMonoLibPath(), PathUtils::GetMonoConfigPath()); #ifndef _RELEASE // Enable Mono signal handling // Makes sure that Mono sends back exceptions it tries to handle, for CE crash handling. mono_set_signal_chaining(true); #endif string monoCmdOptions = ""; if(auto *pArg = gEnv->pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "monoArgs")) monoCmdOptions.append(pArg->GetValue()); // Commandline switch -DEBUG makes the process connect to the debugging server. Warning: Failure to connect to a debugging server WILL result in a crash. // This is currently a WIP feature which requires custom MonoDevelop extensions and other irritating things. const ICmdLineArg* arg = gEnv->pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "DEBUG"); if (arg != nullptr) monoCmdOptions.append("--debugger-agent=transport=dt_socket,address=127.0.0.1:65432,embedding=1"); #ifndef _RELEASE else if(g_pMonoCVars->mono_softBreakpoints) // Soft breakpoints not compatible with debugging server { CryLogAlways(" [Performance Warning] Mono soft breakpoints are enabled!"); // Prevents managed null reference exceptions causing crashes in unmanaged code // See: https://bugzilla.xamarin.com/show_bug.cgi?id=5963 monoCmdOptions.append("--soft-breakpoints"); } #endif char *options = new char[monoCmdOptions.size() + 1]; strcpy(options, monoCmdOptions.c_str()); // Note: iPhone requires AOT compilation, this can be enforced via mono options. TODO: Get Crytek to add CryMobile support to the Free SDK. mono_jit_parse_options(1, &options); #ifndef _RELEASE // Required for mdb's to load for detailed stack traces etc. mono_debug_init(MONO_DEBUG_FORMAT_MONO); #endif m_pConverter = new CConverter(); if(!CompleteInit()) return; if(IFileChangeMonitor *pFileChangeMonitor = gEnv->pFileChangeMonitor) pFileChangeMonitor->RegisterListener(this, "scripts\\"); }
JNIEXPORT jboolean JNICALL Java_com_koushikdutta_monojavabridge_MonoBridge_initializeMono (JNIEnv *env, jclass clazz, jstring debuggerAgentOptions) { // setenv("HOME", "/data/data/com.koushikdutta.twitter/", 1); #ifdef PLATFORM_ANDROID if (debuggerAgentOptions != NULL) { LOGI("Debugger enabled..."); int length = (*env)->GetStringLength(env, debuggerAgentOptions); const jbyte *str = (*env)->GetStringUTFChars(env, debuggerAgentOptions, NULL); char *copy = (char*)malloc(length + 1); copy[length] = NULL; memcpy(copy, str, length); mono_debugger_agent_parse_options(copy); free(copy); (*env)->ReleaseStringUTFChars(env, debuggerAgentOptions, str); mono_debug_init (MONO_DEBUG_FORMAT_MONO); } #endif //guint32 opt = mono_parse_default_optimizations(NULL); //mono_set_defaults (1, opt); //mono_trace_parse_options (""); setenv("MONO_PATH", "/data/data/com.koushikdutta.mono/", 0); #ifdef PLATFORM_ANDROID LOGI("mono_jit_init..."); #endif g_Domain = mono_jit_init (MONOJAVABRIDGE_DLL); #ifdef PLATFORM_ANDROID LOGI("mono_domain_assembly_open...", NULL); #endif g_Assembly = mono_domain_assembly_open (g_Domain, MONOJAVABRIDGE_DLL); if (!g_Assembly) { printf("Unable to load MonoJavaBridge.dll."); return FALSE; } mono_add_internal_call("MonoJavaBridge.JavaBridge::mono_object_to_pointer(object)", mono_objectpointer_conversion); mono_add_internal_call("MonoJavaBridge.JavaBridge::mono_pointer_to_object(intptr)", mono_objectpointer_conversion); mono_add_internal_call("MonoJavaBridge.JavaBridge::log(intptr)", logcat_print); MonoImage *image = mono_assembly_get_image(g_Assembly); MonoMethodDesc* desc = mono_method_desc_new ("MonoJavaBridge.JavaBridge:Initialize(intptr)", 1); MonoMethod* method = mono_method_desc_search_in_image (desc, image); mono_method_desc_free(desc); pointer args[1]; args[0] = &g_JavaVM; mono_runtime_invoke(method, NULL, args, NULL); desc = mono_method_desc_new ("MonoJavaBridge.JavaBridge:Link(intptr,intptr,intptr,intptr)", 1); g_Link = mono_method_desc_search_in_image (desc, image); mono_method_desc_free(desc); desc = mono_method_desc_new ("MonoJavaBridge.JavaBridge:LoadAssembly(intptr)", 1); g_LoadAssembly = mono_method_desc_search_in_image (desc, image); mono_method_desc_free(desc); return TRUE; }
void try_mono() { MonoDomain *domain; MonoAssembly *ma; MonoImage *mi; MonoClass *mc; MonoMethodDesc *mmd; MonoMethod *mm; MonoObject *mo; FILE *mscorlib; char *corlib_data = NULL; void *args [2]; static int x = 123000; args [0] = &x; args [1] = "hello world"; #if defined(__native_client__) mscorlib = fopen("mscorlib.dll", "r"); if (NULL != mscorlib) { size_t size; struct stat st; if (0 == stat("mscorlib.dll", &st)) { size = st.st_size; printf("reading mscorlib.dll, size %ld\n", size); corlib_data = malloc(size); if (corlib_data != NULL) { while (fread(corlib_data, 1, size, mscorlib) != 0) ; if (!ferror(mscorlib)) { mono_set_corlib_data(corlib_data, size); } else { perror("error reading mscorlib.dll"); free(corlib_data); corlib_data = NULL; } } else { perror("Could not allocate memory"); } } else { perror("stat error"); } fclose(mscorlib); } #endif #ifdef AOT_VERSION printf("address of mono_aot_module_mscorlib_info: %p\n", mono_aot_module_mscorlib_info); printf("address of mono_aot_module_hw_info: %p\n", mono_aot_module_hw_info); // mono_jit_set_aot_only(TRUE) should be enabled now. // if not enabled, I suspect we're still jitting... mono_jit_set_aot_only(TRUE); mono_aot_register_module(mono_aot_module_mscorlib_info); mono_aot_register_module(mono_aot_module_hw_info); #endif mono_debug_init(MONO_DEBUG_FORMAT_MONO); domain = mono_jit_init("hw.exe", "v2.0.50727"); printf("mono domain: %p\n", domain); ma = mono_domain_assembly_open(domain, "hw.exe"); printf("mono assembly: %p\n", ma); mi = mono_assembly_get_image(ma); printf("mono image: %p\n", mi); mc = mono_class_from_name(mi, "Test", "HelloWorld"); printf("mono class: %p\n", mc); mmd = mono_method_desc_new("Test.HelloWorld:Foobar(int,string)", TRUE); printf("mono desc method: %p\n", mmd); mm = mono_method_desc_search_in_image(mmd, mi); printf("mono method: %p\n", mm); // add c functions for mono test code to invoke mono_add_internal_call("Test.c_code::my_c_func", (void *) my_c_func); mono_add_internal_call("Test.c_code::my_c_pass", (void *) my_c_pass); mo = mono_runtime_invoke(mm, NULL, args, NULL); printf("mono object: %p\n", mo); if (NULL != corlib_data) free(corlib_data); }
static void InitMono() { std::string citizenClrPath = MakeRelativeNarrowPath("citizen/clr2/lib/"); std::string citizenCfgPath = MakeRelativeNarrowPath("citizen/clr2/cfg/"); mono_set_dirs(citizenClrPath.c_str(), citizenCfgPath.c_str()); #ifdef _WIN32 std::wstring citizenClrLibPath = MakeRelativeCitPath(L"citizen/clr2/lib/mono/4.5/"); SetEnvironmentVariable(L"MONO_PATH", citizenClrLibPath.c_str()); mono_set_crash_chaining(true); #else std::string citizenClrLibPath = MakeRelativeNarrowPath("citizen/clr2/lib/mono/4.5/"); putenv(const_cast<char*>(va("MONO_PATH=%s", citizenClrLibPath))); #endif mono_assembly_setrootdir(citizenClrPath.c_str()); putenv("MONO_DEBUG=casts"); #ifndef IS_FXSERVER mono_security_enable_core_clr(); mono_security_core_clr_set_options((MonoSecurityCoreCLROptions)(MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_DELEGATE | MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_REFLECTION)); mono_security_set_core_clr_platform_callback(CoreClrCallback); #endif char* args[1]; #ifdef _WIN32 args[0] = "--soft-breakpoints"; #else args[0] = "--use-fallback-tls"; #endif mono_jit_parse_options(1, args); mono_debug_init(MONO_DEBUG_FORMAT_MONO); g_rootDomain = mono_jit_init_version("Citizen", "v4.0.30319"); mono_domain_set_config(g_rootDomain, ".", "cfx.config"); mono_install_unhandled_exception_hook([] (MonoObject* exc, void*) { OutputExceptionDetails(exc); }, nullptr); mono_set_crash_chaining(true); mono_add_internal_call("CitizenFX.Core.GameInterface::PrintLog", reinterpret_cast<void*>(GI_PrintLogCall)); mono_add_internal_call("CitizenFX.Core.GameInterface::fwFree", reinterpret_cast<void*>(fwFree)); std::string platformPath = MakeRelativeNarrowPath("citizen/clr2/lib/mono/4.5/CitizenFX.Core.dll"); auto scriptManagerAssembly = mono_domain_assembly_open(g_rootDomain, platformPath.c_str()); if (!scriptManagerAssembly) { FatalError("Could not load CitizenFX.Core.dll.\n"); } auto scriptManagerImage = mono_assembly_get_image(scriptManagerAssembly); bool methodSearchSuccess = true; MonoMethodDesc* description; #define method_search(name, method) description = mono_method_desc_new(name, 1); \ method = mono_method_desc_search_in_image(description, scriptManagerImage); \ mono_method_desc_free(description); \ methodSearchSuccess = methodSearchSuccess && method != NULL MonoMethod* rtInitMethod; method_search("CitizenFX.Core.RuntimeManager:Initialize", rtInitMethod); method_search("CitizenFX.Core.RuntimeManager:GetImplementedClasses", g_getImplementsMethod); method_search("CitizenFX.Core.RuntimeManager:CreateObjectInstance", g_createObjectMethod); if (!methodSearchSuccess) { FatalError("Couldn't find one or more CitizenFX.Core methods.\n"); } MonoObject* exc = nullptr; mono_runtime_invoke(rtInitMethod, nullptr, nullptr, &exc); if (exc) { OutputExceptionDetails(exc); return; } }