commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
136
include/modules/debug_enet/network_debugger.cpp
Normal file
136
include/modules/debug_enet/network_debugger.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
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 <char> &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("<SetDebugSource=<Source=\"%s\"><Line=%d>>", 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 <String> 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("<SetDebugSource=<Source=\"%s\"><Line=%d>>", 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("<VMKill=<Description=\"%s\">>", 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("<SetDebugSource=<Source=\"%s\"><Line=%d>>", source, line));
|
||||
BroadcastNetworkCommand(String::Format("<VMKill=<Description=\"%s\">>", error));
|
||||
}
|
||||
void NetworkDebugger::OnRuntimeException(const char *error)
|
||||
{
|
||||
BroadcastNetworkCommand(String::Format("<VMException=<Description=\"%s\">>", 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);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
167
include/modules/debug_enet/network_debugger_thread.cpp
Normal file
167
include/modules/debug_enet/network_debugger_thread.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "network_debugger_thread.h"
|
||||
#include "network_debugger.h"
|
||||
#include "core/engine.h"
|
||||
#include "metafile/nml.h"
|
||||
#include "log/log.h"
|
||||
|
||||
using namespace GS::Script;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void NetworkDebuggerThread::OnPacketReceived(void *peer, const void *data, size_t size)
|
||||
{
|
||||
using namespace NML;
|
||||
|
||||
Tag tag;
|
||||
Parser::ParseTag(tag, (char *)data, (char *)data + size);
|
||||
|
||||
if (ctl_peer == NULL)
|
||||
{
|
||||
if (tag.name == "HelloMonitor")
|
||||
{
|
||||
Tag *client_version = tag.GetTag("Version;");
|
||||
|
||||
if (client_version->GetInteger() == 1)
|
||||
{
|
||||
ctl_peer = peer;
|
||||
SendString(peer, String::Format("<Welcome=<Platform=\"%s\"><Version=\"%s\">>", Platform::Get().GetName().c_str(), Core::Version));
|
||||
|
||||
ctl.async.QueueMemberCall(&ctl, &NetworkDebugger::OnControllerConnected);
|
||||
|
||||
connected.Set(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
Disconnect(peer);
|
||||
}
|
||||
else if (ctl_peer == peer)
|
||||
ctl.async.QueueMemberCall(&ctl, &NetworkDebugger::OnControllerPacketReceived, Array <char> ((uint)size, (const char *)data));
|
||||
else
|
||||
Disconnect(peer);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void NetworkDebuggerThread::OnPeerConnection(void *peer)
|
||||
{
|
||||
if (ctl_peer == NULL)
|
||||
{
|
||||
SetPeerTimeout(peer, TimeoutVeryLong);
|
||||
SendString(peer, "<Ident>");
|
||||
}
|
||||
else
|
||||
Disconnect(peer);
|
||||
}
|
||||
void NetworkDebuggerThread::OnConnectionClosed(void *peer)
|
||||
{
|
||||
if (peer == ctl_peer)
|
||||
{
|
||||
ctl.async.QueueMemberCall(&ctl, &NetworkDebugger::OnControllerDisconnected);
|
||||
ctl.async.QueueMemberCall(&ctl, &NetworkDebugger::Kill);
|
||||
ctl_peer = NULL;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void NetworkDebuggerThread::SendToController(const GS::String &p)
|
||||
{
|
||||
if (ctl_peer)
|
||||
SendString(ctl_peer, p.c_str());
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool NetworkDebuggerThread::OpenServer(const char *address, int port)
|
||||
{
|
||||
if (!Network::Enet::OpenServer(address, port))
|
||||
return false;
|
||||
|
||||
String host_address;
|
||||
GetHostAddress(host_address);
|
||||
ctl.async.QueueMemberCall(&ctl, &NetworkDebugger::OnNetworkReady, host_address, port);
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
GS::String NetworkDebuggerThread::GetControllerAddress()
|
||||
{
|
||||
String address;
|
||||
if (ctl_peer)
|
||||
GetPeerAddress(ctl_peer, address);
|
||||
return address;
|
||||
}
|
||||
void NetworkDebuggerThread::DisconnectController()
|
||||
{
|
||||
if (ctl_peer)
|
||||
{
|
||||
SendString(ctl_peer, "<EndSession>");
|
||||
connected.Set(0);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void NetworkDebuggerThread::Execute()
|
||||
{
|
||||
Thread::SetName("NetworkDebuggerThread");
|
||||
|
||||
if (!OpenServer(address, port))
|
||||
return;
|
||||
|
||||
for (state.Set(StateWaitingController); state.Get() != StateStop; )
|
||||
{
|
||||
switch (state.Get())
|
||||
{
|
||||
case StateWaitingController: if (ctl_peer) state.Set(StateControllerConnected); break;
|
||||
case StateControllerConnected: if (ctl_peer == NULL) state.Set(StateStop); break; // if controller lost, stop debugger
|
||||
}
|
||||
|
||||
UpdateHost();
|
||||
|
||||
while (async.Execute());
|
||||
|
||||
Platform::Get().Sleep(1);
|
||||
}
|
||||
|
||||
DisconnectController();
|
||||
Close();
|
||||
|
||||
connected.Set(0);
|
||||
|
||||
state.Set(StateStopped);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void NetworkDebuggerThread::Stop()
|
||||
{
|
||||
if (state.Get() != StateStopped)
|
||||
{
|
||||
state.Set(StateStop);
|
||||
while (state.Get() != StateStopped); // spinlock
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
NetworkDebuggerThread::NetworkDebuggerThread(NetworkDebugger &h, const char *a, int p) : ctl(h)
|
||||
{
|
||||
address = a;
|
||||
port = p;
|
||||
|
||||
ctl_peer = NULL;
|
||||
}
|
||||
NetworkDebuggerThread::~NetworkDebuggerThread()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user