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:
parent
7b50c072f9
commit
d8e53cf150
@ -162,9 +162,10 @@ class EXPORT Debug {
|
|||||||
/**
|
/**
|
||||||
* Enable the V8 builtin debug agent. The debugger agent will listen on the
|
* Enable the V8 builtin debug agent. The debugger agent will listen on the
|
||||||
* supplied TCP/IP port for remote debugger connection.
|
* 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
|
* \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) {
|
bool Debug::EnableAgent(const char* name, int port) {
|
||||||
return i::Debugger::StartAgent(port);
|
return i::Debugger::StartAgent(name, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -305,6 +305,11 @@ void RemoteDebugger::HandleKeyboardCommand(char* command) {
|
|||||||
|
|
||||||
|
|
||||||
void ReceiverThread::Run() {
|
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) {
|
while (true) {
|
||||||
// Receive a message.
|
// Receive a message.
|
||||||
i::SmartPointer<char> message =
|
i::SmartPointer<char> message =
|
||||||
|
@ -629,7 +629,7 @@ int Shell::Main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
// Start the debugger agent if requested.
|
// Start the debugger agent if requested.
|
||||||
if (i::FLAG_debugger_agent) {
|
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.
|
// Start the in-process debugger if requested.
|
||||||
|
@ -150,6 +150,10 @@ void DebuggerAgent::OnSessionClosed(DebuggerAgentSession* session) {
|
|||||||
|
|
||||||
|
|
||||||
void DebuggerAgentSession::Run() {
|
void DebuggerAgentSession::Run() {
|
||||||
|
// Send the hello message.
|
||||||
|
bool ok = DebuggerAgentUtil::SendConnectMessage(client_, *agent_->name_);
|
||||||
|
if (!ok) return;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// Read data from the debugger front end.
|
// Read data from the debugger front end.
|
||||||
SmartPointer<char> message = DebuggerAgentUtil::ReceiveMessage(client_);
|
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');
|
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.
|
// 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.
|
// Read body.
|
||||||
char* buffer = NewArray<char>(content_length + 1);
|
char* buffer = NewArray<char>(content_length + 1);
|
||||||
received = ReceiveAll(conn, buffer, content_length);
|
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,
|
bool DebuggerAgentUtil::SendMessage(const Socket* conn,
|
||||||
const Vector<uint16_t> message) {
|
const Vector<uint16_t> message) {
|
||||||
static const int kBufferSize = 80;
|
static const int kBufferSize = 80;
|
||||||
@ -291,7 +349,7 @@ bool DebuggerAgentUtil::SendMessage(const Socket* conn,
|
|||||||
// Send the header.
|
// Send the header.
|
||||||
int len;
|
int len;
|
||||||
len = OS::SNPrintF(Vector<char>(buffer, kBufferSize),
|
len = OS::SNPrintF(Vector<char>(buffer, kBufferSize),
|
||||||
"Content-Length: %d\n", utf8_len);
|
"%s: %d\n", kContentLength, utf8_len);
|
||||||
conn->Send(buffer, len);
|
conn->Send(buffer, len);
|
||||||
|
|
||||||
// Terminate header with empty line.
|
// Terminate header with empty line.
|
||||||
|
@ -42,8 +42,9 @@ class DebuggerAgentSession;
|
|||||||
// handles connection from a remote debugger.
|
// handles connection from a remote debugger.
|
||||||
class DebuggerAgent: public Thread {
|
class DebuggerAgent: public Thread {
|
||||||
public:
|
public:
|
||||||
explicit DebuggerAgent(int port)
|
explicit DebuggerAgent(const char* name, int port)
|
||||||
: port_(port), server_(OS::CreateSocket()), terminate_(false),
|
: port_(port), name_(StrDup(name)),
|
||||||
|
server_(OS::CreateSocket()), terminate_(false),
|
||||||
session_access_(OS::CreateMutex()), session_(NULL),
|
session_access_(OS::CreateMutex()), session_(NULL),
|
||||||
terminate_now_(OS::CreateSemaphore(0)) {}
|
terminate_now_(OS::CreateSemaphore(0)) {}
|
||||||
~DebuggerAgent() { delete server_; }
|
~DebuggerAgent() { delete server_; }
|
||||||
@ -57,6 +58,7 @@ class DebuggerAgent: public Thread {
|
|||||||
void CloseSession();
|
void CloseSession();
|
||||||
void OnSessionClosed(DebuggerAgentSession* session);
|
void OnSessionClosed(DebuggerAgentSession* session);
|
||||||
|
|
||||||
|
SmartPointer<const char> name_; // Name of the embedding application.
|
||||||
int port_; // Port to use for the agent.
|
int port_; // Port to use for the agent.
|
||||||
Socket* server_; // Server socket for listen/accept.
|
Socket* server_; // Server socket for listen/accept.
|
||||||
bool terminate_; // Termination flag.
|
bool terminate_; // Termination flag.
|
||||||
@ -101,6 +103,8 @@ class DebuggerAgentUtil {
|
|||||||
static int kContentLengthSize;
|
static int kContentLengthSize;
|
||||||
|
|
||||||
static SmartPointer<char> ReceiveMessage(const Socket* conn);
|
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 Vector<uint16_t> message);
|
||||||
static bool SendMessage(const Socket* conn,
|
static bool SendMessage(const Socket* conn,
|
||||||
const v8::Handle<v8::String> message);
|
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()) {
|
if (Socket::Setup()) {
|
||||||
agent_ = new DebuggerAgent(port);
|
agent_ = new DebuggerAgent(name, port);
|
||||||
agent_->Start();
|
agent_->Start();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -441,7 +441,7 @@ class Debugger {
|
|||||||
bool* pending_exception);
|
bool* pending_exception);
|
||||||
|
|
||||||
// Start the debugger agent listening on the provided port.
|
// 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.
|
// Stop the debugger agent.
|
||||||
static void StopAgent();
|
static void StopAgent();
|
||||||
|
@ -3840,12 +3840,12 @@ TEST(DebuggerAgent) {
|
|||||||
i::Socket::Setup();
|
i::Socket::Setup();
|
||||||
|
|
||||||
// Test starting and stopping the agent without any client connection.
|
// Test starting and stopping the agent without any client connection.
|
||||||
i::Debugger::StartAgent(kPort);
|
i::Debugger::StartAgent("test", kPort);
|
||||||
i::Debugger::StopAgent();
|
i::Debugger::StopAgent();
|
||||||
|
|
||||||
// Test starting the agent, connecting a client and shutting down the agent
|
// Test starting the agent, connecting a client and shutting down the agent
|
||||||
// with the client connected.
|
// with the client connected.
|
||||||
ok = i::Debugger::StartAgent(kPort);
|
ok = i::Debugger::StartAgent("test", kPort);
|
||||||
CHECK(ok);
|
CHECK(ok);
|
||||||
i::Socket* client = i::OS::CreateSocket();
|
i::Socket* client = i::OS::CreateSocket();
|
||||||
ok = client->Connect("localhost", port_str);
|
ok = client->Connect("localhost", port_str);
|
||||||
@ -3858,7 +3858,7 @@ TEST(DebuggerAgent) {
|
|||||||
i::Socket* server = i::OS::CreateSocket();
|
i::Socket* server = i::OS::CreateSocket();
|
||||||
server->Bind(kPort);
|
server->Bind(kPort);
|
||||||
|
|
||||||
i::Debugger::StartAgent(kPort);
|
i::Debugger::StartAgent("test", kPort);
|
||||||
i::Debugger::StopAgent();
|
i::Debugger::StopAgent();
|
||||||
|
|
||||||
delete server;
|
delete server;
|
||||||
|
Loading…
Reference in New Issue
Block a user