Commit d8e53cf1 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Extend debugger agent protocol with a connect message.Added a name of the...

Extend debugger agent protocol with a connect message.Added a name of the embedding application when enabeling the debugger agent.Send a connection message from the debugger agent to the remote debugger when connecting. This message contains the V8 version, the protcol version (currently 1) and the name of the embedding application. Currently this information is just printed raw as received.
Review URL: http://codereview.chromium.org/52012

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1579 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7b50c072
......@@ -162,9 +162,10 @@ class EXPORT Debug {
/**
* Enable the V8 builtin debug agent. The debugger agent will listen on the
* supplied TCP/IP port for remote debugger connection.
* \param name the name of the embedding application
* \param port the TCP/IP port to listen on
*/
static bool EnableAgent(int port);
static bool EnableAgent(const char* name, int port);
};
......
......@@ -3113,8 +3113,8 @@ Handle<Value> Debug::Call(v8::Handle<v8::Function> fun,
}
bool Debug::EnableAgent(int port) {
return i::Debugger::StartAgent(port);
bool Debug::EnableAgent(const char* name, int port) {
return i::Debugger::StartAgent(name, port);
}
......
......@@ -305,6 +305,11 @@ void RemoteDebugger::HandleKeyboardCommand(char* command) {
void ReceiverThread::Run() {
// Receive the connect message (with empty body).
i::SmartPointer<char> message =
i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn());
ASSERT(*message == NULL);
while (true) {
// Receive a message.
i::SmartPointer<char> message =
......
......@@ -629,7 +629,7 @@ int Shell::Main(int argc, char* argv[]) {
// Start the debugger agent if requested.
if (i::FLAG_debugger_agent) {
v8::Debug::EnableAgent(i::FLAG_debugger_port);
v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port);
}
// Start the in-process debugger if requested.
......
......@@ -150,6 +150,10 @@ void DebuggerAgent::OnSessionClosed(DebuggerAgentSession* session) {
void DebuggerAgentSession::Run() {
// Send the hello message.
bool ok = DebuggerAgentUtil::SendConnectMessage(client_, *agent_->name_);
if (!ok) return;
while (true) {
// Read data from the debugger front end.
SmartPointer<char> message = DebuggerAgentUtil::ReceiveMessage(client_);
......@@ -252,6 +256,9 @@ SmartPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) {
}
content_length = 10 * content_length + (value[i] - '0');
}
} else {
// For now just print all other headers than Content-Length.
PrintF("%s: %s\n", key, value);
}
// Start collecting new header.
......@@ -264,6 +271,11 @@ SmartPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) {
}
}
// Return now if no body.
if (content_length == 0) {
return SmartPointer<char>();
}
// Read body.
char* buffer = NewArray<char>(content_length + 1);
received = ReceiveAll(conn, buffer, content_length);
......@@ -277,6 +289,52 @@ SmartPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) {
}
bool DebuggerAgentUtil::SendConnectMessage(const Socket* conn,
const char* embedding_host) {
static const int kBufferSize = 80;
char buffer[kBufferSize]; // Sending buffer.
bool ok;
int len;
// Send the header.
len = OS::SNPrintF(Vector<char>(buffer, kBufferSize),
"Type: connect\n");
ok = conn->Send(buffer, len);
if (!ok) return false;
len = OS::SNPrintF(Vector<char>(buffer, kBufferSize),
"V8-Version: %s\n", v8::V8::GetVersion());
ok = conn->Send(buffer, len);
if (!ok) return false;
len = OS::SNPrintF(Vector<char>(buffer, kBufferSize),
"Protocol-Version: 1\n");
ok = conn->Send(buffer, len);
if (!ok) return false;
if (embedding_host != NULL) {
len = OS::SNPrintF(Vector<char>(buffer, kBufferSize),
"Embedding-Host: %s\n", embedding_host);
ok = conn->Send(buffer, len);
if (!ok) return false;
}
len = OS::SNPrintF(Vector<char>(buffer, kBufferSize),
"%s: 0\n", kContentLength);
ok = conn->Send(buffer, len);
if (!ok) return false;
// Terminate header with empty line.
len = OS::SNPrintF(Vector<char>(buffer, kBufferSize), "\n");
ok = conn->Send(buffer, len);
if (!ok) return false;
// No body for connect message.
return true;
}
bool DebuggerAgentUtil::SendMessage(const Socket* conn,
const Vector<uint16_t> message) {
static const int kBufferSize = 80;
......@@ -291,7 +349,7 @@ bool DebuggerAgentUtil::SendMessage(const Socket* conn,
// Send the header.
int len;
len = OS::SNPrintF(Vector<char>(buffer, kBufferSize),
"Content-Length: %d\n", utf8_len);
"%s: %d\n", kContentLength, utf8_len);
conn->Send(buffer, len);
// Terminate header with empty line.
......
......@@ -42,8 +42,9 @@ class DebuggerAgentSession;
// handles connection from a remote debugger.
class DebuggerAgent: public Thread {
public:
explicit DebuggerAgent(int port)
: port_(port), server_(OS::CreateSocket()), terminate_(false),
explicit DebuggerAgent(const char* name, int port)
: port_(port), name_(StrDup(name)),
server_(OS::CreateSocket()), terminate_(false),
session_access_(OS::CreateMutex()), session_(NULL),
terminate_now_(OS::CreateSemaphore(0)) {}
~DebuggerAgent() { delete server_; }
......@@ -57,6 +58,7 @@ class DebuggerAgent: public Thread {
void CloseSession();
void OnSessionClosed(DebuggerAgentSession* session);
SmartPointer<const char> name_; // Name of the embedding application.
int port_; // Port to use for the agent.
Socket* server_; // Server socket for listen/accept.
bool terminate_; // Termination flag.
......@@ -101,6 +103,8 @@ class DebuggerAgentUtil {
static int kContentLengthSize;
static SmartPointer<char> ReceiveMessage(const Socket* conn);
static bool SendConnectMessage(const Socket* conn,
const char* embedding_host);
static bool SendMessage(const Socket* conn, const Vector<uint16_t> message);
static bool SendMessage(const Socket* conn,
const v8::Handle<v8::String> message);
......
......@@ -1828,9 +1828,9 @@ Handle<Object> Debugger::Call(Handle<JSFunction> fun,
}
bool Debugger::StartAgent(int port) {
bool Debugger::StartAgent(const char* name, int port) {
if (Socket::Setup()) {
agent_ = new DebuggerAgent(port);
agent_ = new DebuggerAgent(name, port);
agent_->Start();
return true;
}
......
......@@ -441,7 +441,7 @@ class Debugger {
bool* pending_exception);
// Start the debugger agent listening on the provided port.
static bool StartAgent(int port);
static bool StartAgent(const char* name, int port);
// Stop the debugger agent.
static void StopAgent();
......
......@@ -3840,12 +3840,12 @@ TEST(DebuggerAgent) {
i::Socket::Setup();
// Test starting and stopping the agent without any client connection.
i::Debugger::StartAgent(kPort);
i::Debugger::StartAgent("test", kPort);
i::Debugger::StopAgent();
// Test starting the agent, connecting a client and shutting down the agent
// with the client connected.
ok = i::Debugger::StartAgent(kPort);
ok = i::Debugger::StartAgent("test", kPort);
CHECK(ok);
i::Socket* client = i::OS::CreateSocket();
ok = client->Connect("localhost", port_str);
......@@ -3858,7 +3858,7 @@ TEST(DebuggerAgent) {
i::Socket* server = i::OS::CreateSocket();
server->Bind(kPort);
i::Debugger::StartAgent(kPort);
i::Debugger::StartAgent("test", kPort);
i::Debugger::StopAgent();
delete server;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment