/**
* 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);
};
}
-bool Debug::EnableAgent(int port) {
- return i::Debugger::StartAgent(port);
+bool Debug::EnableAgent(const char* name, int port) {
+ return i::Debugger::StartAgent(name, port);
}
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 =
// 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.
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_);
}
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.
}
}
+ // 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);
}
+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;
// 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.
// 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_; }
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.
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);
}
-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;
}
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();
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);
i::Socket* server = i::OS::CreateSocket();
server->Bind(kPort);
- i::Debugger::StartAgent(kPort);
+ i::Debugger::StartAgent("test", kPort);
i::Debugger::StopAgent();
delete server;