/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #include "network_debugger.h" #include "network_debugger_thread.h" #include "metafile/nml.h" using namespace GS; using namespace GS::Script; //------------------------------------------------------------------------------ void NetworkDebugger::OnControllerPacketReceived(const Array &data) { using namespace NML; Tag tag; Parser::ParseTag(tag, data.Start(), data.End()); //---------------------------------------------------------------------- if (tag.name == "Start") start_signal = true; else if (tag.name == "StepInto") debugger->StepInto(); else if (tag.name == "StepOver") debugger->Step(); else if (tag.name == "StepOut") debugger->StepOut(); else if (tag.name == "Resume") debugger->Resume(); //---------------------------------------------------------------------- //---------------------------------------------------------------------- else if (tag.name == "SetDebugStackFrame") debugger->SetDebugStackFrame(tag.GetInteger()); else if (tag.name == "SetTopDebugStackFrame") debugger->SetDebugStackFrame(-1); else if (tag.name == "RequestDebugStackFrameSource") { const char *source; int line; debugger->GetStackFrameSource(source, line); if (source) BroadcastNetworkCommand(String::Format(">", source, line)); } else if (tag.name == "RequestDebugCallStack") BroadcastNetworkCommand(GetCallstack()); else if (tag.name == "RequestDebugStackFrameLocals") BroadcastNetworkCommand(GetDebugStackFrameLocals()); else if (tag.name == "SetBreakpoints") debugger->SetBreakpoints(tag); //---------------------------------------------------------------------- } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ String NetworkDebugger::GetPeerAddress() { ASync::Future address; thread->async.QueueMemberCall(address, thread, &NetworkDebuggerThread::GetControllerAddress); return address.Get(); } bool NetworkDebugger::IsConnected() const { return thread->IsConnected(); } void NetworkDebugger::Stop() { thread->Stop(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void NetworkDebugger::BroadcastNetworkCommand(const String &cmd) { // Queue an asynchronous call to the controller thread. thread->async.QueueMemberCall(thread, &NetworkDebuggerThread::SendToController, cmd); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void NetworkDebugger::OnSuspendExecution(const char *source, int line) { // Set callstack, stack frame locals and source. BroadcastNetworkCommand(GetCallstack()); BroadcastNetworkCommand(debugger->GetStackFrameLocals()); BroadcastNetworkCommand(String::Format(">", source, line)); } bool NetworkDebugger::OnUpdateSuspendedExecution() { async.Execute(); // [EJ] execute calls pushed by the debug thread to us so that we may receive new packets return thread->IsConnected(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void NetworkDebugger::OnFatalError(const char *reason) { BroadcastNetworkCommand(String::Format(">", reason)); } void NetworkDebugger::OnCompilerError(const char *error, const char *source, int line) { // Make sure the error location is displayed prior to the VM kill event being received. BroadcastNetworkCommand(String::Format(">", source, line)); BroadcastNetworkCommand(String::Format(">", error)); } void NetworkDebugger::OnRuntimeException(const char *error) { BroadcastNetworkCommand(String::Format(">", error)); /* ...then suspend all execution beside the server inspection communication channels. The VM along with the executing program will die when this function returns. */ while ((vm->GetState() == IVM::StateExceptionThrown) && thread->IsConnected()) { async.Execute(); Threading::Thread::Switch(); } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ NetworkDebugger::NetworkDebugger(IVM *vm, IDebugger *debugger, const char *address, int port) : IDebuggerProfiler(vm, debugger) { start_signal = false; thread = new NetworkDebuggerThread(*this, address, port); thread->Start(); } NetworkDebugger::~NetworkDebugger() { _safe_delete(thread); } //------------------------------------------------------------------------------