Extend debugger agent protocol with a connect message.Added a name of the embedding...
authorsgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 23 Mar 2009 22:23:39 +0000 (22:23 +0000)
committersgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 23 Mar 2009 22:23:39 +0000 (22:23 +0000)
Review URL: http://codereview.chromium.org/52012

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1579 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

include/v8-debug.h
src/api.cc
src/d8-debug.cc
src/d8.cc
src/debug-agent.cc
src/debug-agent.h
src/debug.cc
src/debug.h
test/cctest/test-debug.cc

index 42bb24f..74750d1 100644 (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);
 };
 
 
index 27efc4e..52e70b0 100644 (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);
 }
 
 
index eab0f4f..4e0243a 100644 (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 =
index 2d10744..3e4f2f2 100644 (file)
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -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.
index 4dc050e..abf684d 100644 (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.
index 2e97604..3a49cb0 100644 (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);
index 947a808..7e0b298 100644 (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;
   }
index b8457e0..c29b49b 100644 (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();
index 2543605..54013c6 100644 (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;