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
This commit is contained in:
sgjesse@chromium.org 2009-03-23 22:23:39 +00:00
parent 7b50c072f9
commit d8e53cf150
9 changed files with 81 additions and 13 deletions

View File

@ -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);
};

View File

@ -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);
}

View File

@ -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 =

View File

@ -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.

View File

@ -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.

View File

@ -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);

View File

@ -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;
}

View File

@ -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();

View File

@ -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;