[Server] Add --debug option to launch options.

Add Soft-Mode Debugger for Mono.
experimental-mono
Koncord 6 years ago
parent f37c252dbe
commit 6cbf6f05a1

@ -292,3 +292,13 @@ void LangLua::AddPackageCPath(const std::string& path)
{ {
packageCPath.emplace(path); packageCPath.emplace(path);
} }
void LangLua::Init()
{
}
void LangLua::Free()
{
}

@ -48,6 +48,9 @@ public:
private: private:
static std::set<std::string> packageCPath; static std::set<std::string> packageCPath;
static std::set<std::string> packagePath; static std::set<std::string> packagePath;
static void Init();
static void Free();
}; };

@ -8,8 +8,9 @@
#include <mono/jit/jit.h> #include <mono/jit/jit.h>
#include <mono/metadata/assembly.h> #include <mono/metadata/assembly.h>
#include <mono/metadata/mono-config.h> #include <mono/metadata/mono-config.h>
#include <apps/openmw-mp/Script/ScriptFunctions.hpp> #include <mono/metadata/mono-debug.h>
#include <apps/openmw-mp/Script/API/TimerAPI.hpp> #include <Script/ScriptFunctions.hpp>
#include <Script/API/TimerAPI.hpp>
#include "LangMono.hpp" #include "LangMono.hpp"
static MonoDomain *domain = nullptr; // shared domain static MonoDomain *domain = nullptr; // shared domain
@ -114,13 +115,10 @@ lib_t LangMono::GetInterface()
LangMono::LangMono() LangMono::LangMono()
{ {
instance = new MonoInstance; instance = new MonoInstance;
Init();
} }
LangMono::LangMono(MonoInstance *instance) : instance(instance) LangMono::LangMono(MonoInstance *instance) : instance(instance)
{ {
Init();
} }
LangMono::~LangMono() LangMono::~LangMono()
@ -133,12 +131,37 @@ void LangMono::Init()
if (domain != nullptr) if (domain != nullptr)
return; return;
domain = mono_jit_init("TES3MP Mono VM"); // will leak :P if (Script::IsDebugMode())
{
std::string debugServerAddress = "127.0.0.1:10000";
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Waiting for debugger on %s...", debugServerAddress.c_str());
std::string connectionString = "--debugger-agent=transport=dt_socket,server=y,address=" + debugServerAddress;
std::vector<const char*> options {
"--soft-breakpoints",
connectionString.c_str()
};
mono_jit_parse_options(options.size(), (char**) options.data());
mono_debug_init(MONO_DEBUG_FORMAT_MONO);
}
domain = mono_jit_init("TES3MP Mono VM");
if (Script::IsDebugMode())
{
mono_debug_domain_create(domain);
}
mono_add_internal_call("TES3MPSharp.TES3MP::CreateTimerEx", (void*) &LangMono::CreateTimerEx); mono_add_internal_call("TES3MPSharp.TES3MP::CreateTimerEx", (void*) &LangMono::CreateTimerEx);
mono_add_internal_call("TES3MPSharp.TES3MP::MakePublic", (void*) &LangMono::MakePublic); mono_add_internal_call("TES3MPSharp.TES3MP::MakePublic", (void*) &LangMono::MakePublic);
mono_add_internal_call("TES3MPSharp.TES3MP::CallPublic", (void*) &LangMono::CallPublic); mono_add_internal_call("TES3MPSharp.TES3MP::CallPublic", (void*) &LangMono::CallPublic);
} }
void LangMono::Free()
{
mono_domain_free(domain, 0);
}
std::vector<MonoClass *> getInstanceClassList(MonoImage *image, const std::string &parentName) std::vector<MonoClass *> getInstanceClassList(MonoImage *image, const std::string &parentName)
{ {
std::vector<MonoClass *> classes; std::vector<MonoClass *> classes;

@ -67,6 +67,6 @@ public:
static void MakePublic(MonoObject *delegate, const char *name) noexcept; static void MakePublic(MonoObject *delegate, const char *name) noexcept;
static MonoObject *CallPublic(const char *name, MonoArray *args); static MonoObject *CallPublic(const char *name, MonoArray *args);
private: static void Init();
void Init(); static void Free();
}; };

@ -100,3 +100,13 @@ LangNative::~LangNative()
{ {
} }
void LangNative::Init()
{
}
void LangNative::Free()
{
}

@ -22,6 +22,8 @@ public:
virtual boost::any Call(const char *name, const char *argl, int buf, ...) override; virtual boost::any Call(const char *name, const char *argl, int buf, ...) override;
virtual boost::any Call(const char *name, const char *argl, const std::vector<boost::any> &args) override; virtual boost::any Call(const char *name, const char *argl, const std::vector<boost::any> &args) override;
static void Init();
static void Free();
}; };

@ -17,6 +17,7 @@ using namespace std;
Script::ScriptList Script::scripts; Script::ScriptList Script::scripts;
std::string Script::moddir; std::string Script::moddir;
bool Script::debugMode = false;
inline bool Load(Language *lang, const std::string &path) inline bool Load(Language *lang, const std::string &path)
{ {
@ -133,3 +134,35 @@ const char* Script::GetModDir()
{ {
return moddir.c_str(); return moddir.c_str();
} }
bool Script::IsDebugMode()
{
return debugMode;
}
void Script::EnableDebugMode()
{
debugMode = true;
}
void Script::Init()
{
#ifdef ENABLE_MONO
LangMono::Init();
#endif
#ifdef ENABLE_LUA
LangLua::Init();
#endif
LangNative::Init();
}
void Script::Free()
{
#ifdef ENABLE_MONO
LangMono::Free();
#endif
#ifdef ENABLE_LUA
LangLua::Free();
#endif
LangNative::Free();
}

@ -57,9 +57,14 @@ private:
protected: protected:
static std::string moddir; static std::string moddir;
static bool debugMode;
public: public:
~Script(); ~Script();
static void Init();
static void Free();
static bool IsDebugMode();
static void EnableDebugMode();
static void LoadScript(const char *script, const char* base); static void LoadScript(const char *script, const char* base);
static void LoadScripts(char* scripts, const char* base); static void LoadScripts(char* scripts, const char* base);
static void UnloadScripts(); static void UnloadScripts();

@ -134,6 +134,7 @@ boost::program_options::variables_map launchOptions(int argc, char *argv[], File
desc.add_options() desc.add_options()
("resources", bpo::value<Files::EscapeHashString>()->default_value("resources"), "set resources directory") ("resources", bpo::value<Files::EscapeHashString>()->default_value("resources"), "set resources directory")
("debug", bpo::value<bool>()->implicit_value(true)->default_value(false), "Enable debug mode for scripts (if supported)")
("no-logs", bpo::value<bool>()->implicit_value(true)->default_value(false), ("no-logs", bpo::value<bool>()->implicit_value(true)->default_value(false),
"Do not write logs. Useful for daemonizing."); "Do not write logs. Useful for daemonizing.");
@ -264,6 +265,9 @@ int main(int argc, char *argv[])
try try
{ {
if (variables["debug"].as<bool>())
Script::EnableDebugMode();
Script::Init();
for (auto plugin : plugins) for (auto plugin : plugins)
Script::LoadScript(plugin.c_str(), plugin_home.c_str()); Script::LoadScript(plugin.c_str(), plugin_home.c_str());
@ -331,6 +335,7 @@ int main(int argc, char *argv[])
code = networking.mainLoop(); code = networking.mainLoop();
networking.getMasterClient()->Stop(); networking.getMasterClient()->Stop();
Script::Free();
} }
catch (std::exception &e) catch (std::exception &e)
{ {

Loading…
Cancel
Save