Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Unified Diff: src/d8-debug.cc

Issue 40011: Add remote debugging front end to developer shell.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/d8-debug.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/d8-debug.cc
===================================================================
--- src/d8-debug.cc (revision 1405)
+++ src/d8-debug.cc (working copy)
@@ -28,6 +28,8 @@
#include "d8.h"
#include "d8-debug.h"
+#include "platform.h"
+#include "debug-agent.h"
namespace v8 {
@@ -142,4 +144,197 @@
}
+void RunRemoteDebugger(int port) {
+ RemoteDebugger debugger(port);
+ debugger.Run();
+}
+
+
+void RemoteDebugger::Run() {
+ bool ok;
+
+ // Make sure that socket support is initialized.
+ ok = i::Socket::Setup();
+ if (!ok) {
+ printf("Unable to initialize socket support %d\n", i::Socket::LastError());
+ return;
+ }
+
+ // Connect to the debugger agent.
+ conn_ = i::OS::CreateSocket();
+ static const int kPortStrSize = 6;
+ char port_str[kPortStrSize];
+ i::OS::SNPrintF(i::Vector<char>(port_str, kPortStrSize), "%d", port_);
+ ok = conn_->Connect("localhost", port_str);
+ if (!ok) {
+ printf("Unable to connect to debug agent %d\n", i::Socket::LastError());
+ return;
+ }
+
+ // Start the receiver thread.
+ ReceiverThread receiver(this);
+ receiver.Start();
+
+ // Start the keyboard thread.
+ KeyboardThread keyboard(this);
+ keyboard.Start();
+
+ // Process events received from debugged VM and from the keyboard.
+ bool terminate = false;
+ while (!terminate) {
+ event_available_->Wait();
+ RemoteDebuggerEvent* event = GetEvent();
+ switch (event->type()) {
+ case RemoteDebuggerEvent::kMessage:
+ HandleMessageReceived(event->data());
+ break;
+ case RemoteDebuggerEvent::kKeyboard:
+ HandleKeyboardCommand(event->data());
+ break;
+ case RemoteDebuggerEvent::kDisconnect:
+ terminate = true;
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+ delete event;
+ }
+
+ // Wait for the receiver thread to end.
+ receiver.Join();
+}
+
+
+void RemoteDebugger::MessageReceived(i::SmartPointer<char> message) {
+ RemoteDebuggerEvent* event =
+ new RemoteDebuggerEvent(RemoteDebuggerEvent::kMessage, message);
+ AddEvent(event);
+}
+
+
+void RemoteDebugger::KeyboardCommand(i::SmartPointer<char> command) {
+ RemoteDebuggerEvent* event =
+ new RemoteDebuggerEvent(RemoteDebuggerEvent::kKeyboard, command);
+ AddEvent(event);
+}
+
+
+void RemoteDebugger::ConnectionClosed() {
+ RemoteDebuggerEvent* event =
+ new RemoteDebuggerEvent(RemoteDebuggerEvent::kDisconnect,
+ i::SmartPointer<char>());
+ AddEvent(event);
+}
+
+
+void RemoteDebugger::AddEvent(RemoteDebuggerEvent* event) {
+ i::ScopedLock lock(event_access_);
+ if (head_ == NULL) {
+ ASSERT(tail_ == NULL);
+ head_ = event;
+ tail_ = event;
+ } else {
+ ASSERT(tail_ != NULL);
+ tail_->set_next(event);
+ tail_ = event;
+ }
+ event_available_->Signal();
+}
+
+
+RemoteDebuggerEvent* RemoteDebugger::GetEvent() {
+ i::ScopedLock lock(event_access_);
+ ASSERT(head_ != NULL);
+ RemoteDebuggerEvent* result = head_;
+ head_ = head_->next();
+ if (head_ == NULL) {
+ ASSERT(tail_ == result);
+ tail_ = NULL;
+ }
+ return result;
+}
+
+
+void RemoteDebugger::HandleMessageReceived(char* message) {
+ HandleScope scope;
+
+ // Print the event details.
+ TryCatch try_catch;
+ Handle<Object> details =
+ Shell::DebugMessageDetails(Handle<String>::Cast(String::New(message)));
+ if (try_catch.HasCaught()) {
+ Shell::ReportException(&try_catch);
+ return;
+ }
+ String::Utf8Value str(details->Get(String::New("text")));
+ if (str.length() == 0) {
+ // Empty string is used to signal not to process this event.
+ return;
+ }
+ if (*str != NULL) {
+ printf("%s\n", *str);
+ } else {
+ printf("???\n");
+ }
+ printf("dbg> ");
+}
+
+
+void RemoteDebugger::HandleKeyboardCommand(char* command) {
+ HandleScope scope;
+
+ // Convert the debugger command to a JSON debugger request.
+ TryCatch try_catch;
+ Handle<Value> request =
+ Shell::DebugCommandToJSONRequest(String::New(command));
+ if (try_catch.HasCaught()) {
+ Shell::ReportException(&try_catch);
+ return;
+ }
+
+ // If undefined is returned the command was handled internally and there is
+ // no JSON to send.
+ if (request->IsUndefined()) {
+ return;
+ }
+
+ // Send the JSON debugger request.
+ i::DebuggerAgentUtil::SendMessage(conn_, Handle<String>::Cast(request));
+}
+
+
+void ReceiverThread::Run() {
+ while (true) {
+ // Receive a message.
+ i::SmartPointer<char> message =
+ i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn());
+ if (*message == NULL) {
+ remote_debugger_->ConnectionClosed();
+ return;
+ }
+
+ // Pass the message to the main thread.
+ remote_debugger_->MessageReceived(message);
+ }
+}
+
+
+void KeyboardThread::Run() {
+ static const int kBufferSize = 256;
+ while (true) {
+ // read keyboard input.
+ char command[kBufferSize];
+ char* str = fgets(command, kBufferSize, stdin);
+ if (str == NULL) {
+ break;
+ }
+
+ // Pass the keyboard command to the main thread.
+ remote_debugger_->KeyboardCommand(
+ i::SmartPointer<char>(i::OS::StrDup(command)));
+ }
+}
+
+
} // namespace v8
« no previous file with comments | « src/d8-debug.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698