diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index bcf685e6e3ac..aaf68836d0c3 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -8,7 +8,6 @@ #include "atom/browser/atom_browser_context.h" #include "atom/browser/browser.h" #include "atom/browser/javascript_environment.h" -#include "atom/browser/node_debugger.h" #include "atom/common/api/atom_bindings.h" #include "atom/common/node_bindings.h" #include "base/command_line.h" @@ -60,16 +59,9 @@ void AtomBrowserMainParts::PostEarlyInitialization() { node_bindings_->Initialize(); - // Support the "--debug" switch. - node_debugger_.reset(new NodeDebugger(js_env_->isolate())); - // Create the global environment. global_env = node_bindings_->CreateEnvironment(js_env_->context()); - // Make sure node can get correct environment when debugging. - if (node_debugger_->IsRunning()) - global_env->AssignToContext(v8::Debug::GetDebugContext()); - // Add atom-shell extended APIs. atom_bindings_->BindTo(js_env_->isolate(), global_env->process_object()); diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index a825862ff9be..6ca0686655ba 100644 --- a/atom/browser/atom_browser_main_parts.h +++ b/atom/browser/atom_browser_main_parts.h @@ -14,7 +14,6 @@ class AtomBindings; class Browser; class JavascriptEnvironment; class NodeBindings; -class NodeDebugger; class AtomBrowserMainParts : public brightray::BrowserMainParts { public: @@ -46,7 +45,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { scoped_ptr js_env_; scoped_ptr node_bindings_; scoped_ptr atom_bindings_; - scoped_ptr node_debugger_; base::Timer gc_timer_; diff --git a/atom/browser/node_debugger.cc b/atom/browser/node_debugger.cc deleted file mode 100644 index 4e2302763c7e..000000000000 --- a/atom/browser/node_debugger.cc +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2014 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "atom/browser/node_debugger.h" - -#include - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "content/public/browser/browser_thread.h" -#include "net/socket/tcp_listen_socket.h" - -#include "atom/common/node_includes.h" - -namespace atom { - -namespace { - -// NodeDebugger is stored in Isolate's data, slots 0, 1, 3 have already been -// taken by gin, blink and node, using 2 is a safe option for now. -const int kIsolateSlot = 2; - -const char* kContentLength = "Content-Length"; - -} // namespace - -NodeDebugger::NodeDebugger(v8::Isolate* isolate) - : isolate_(isolate), - thread_("NodeDebugger"), - content_length_(-1), - weak_factory_(this) { - bool use_debug_agent = false; - int port = 5858; - bool wait_for_connection = false; - - std::string port_str; - base::CommandLine* cmd = base::CommandLine::ForCurrentProcess(); - if (cmd->HasSwitch("debug")) { - use_debug_agent = true; - port_str = cmd->GetSwitchValueASCII("debug"); - } - if (cmd->HasSwitch("debug-brk")) { - use_debug_agent = true; - wait_for_connection = true; - port_str = cmd->GetSwitchValueASCII("debug-brk"); - } - - if (use_debug_agent) { - if (!port_str.empty()) - base::StringToInt(port_str, &port); - - isolate_->SetData(kIsolateSlot, this); - v8::Debug::SetMessageHandler(DebugMessageHandler); - - if (wait_for_connection) - v8::Debug::DebugBreak(isolate_); - - // Start a new IO thread. - base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; - if (!thread_.StartWithOptions(options)) { - LOG(ERROR) << "Unable to start debugger thread"; - return; - } - - // Start the server in new IO thread. - thread_.message_loop()->PostTask( - FROM_HERE, - base::Bind(&NodeDebugger::StartServer, weak_factory_.GetWeakPtr(), - port)); - } -} - -NodeDebugger::~NodeDebugger() { - thread_.Stop(); -} - -bool NodeDebugger::IsRunning() const { - return thread_.IsRunning(); -} - -void NodeDebugger::StartServer(int port) { - server_ = net::TCPListenSocket::CreateAndListen("127.0.0.1", port, this); - if (!server_) { - LOG(ERROR) << "Cannot start debugger server"; - return; - } -} - -void NodeDebugger::CloseSession() { - accepted_socket_.reset(); -} - -void NodeDebugger::OnMessage(const std::string& message) { - if (message.find("\"type\":\"request\",\"command\":\"disconnect\"}") != - std::string::npos) - CloseSession(); - - base::string16 message16 = base::UTF8ToUTF16(message); - v8::Debug::SendCommand( - isolate_, - reinterpret_cast(message16.data()), message16.size()); - - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, - base::Bind(&v8::Debug::ProcessDebugMessages)); -} - -void NodeDebugger::SendMessage(const std::string& message) { - if (accepted_socket_) { - std::string header = base::StringPrintf( - "%s: %d\r\n\r\n", kContentLength, static_cast(message.size())); - accepted_socket_->Send(header); - accepted_socket_->Send(message); - } -} - -void NodeDebugger::SendConnectMessage() { - accepted_socket_->Send(base::StringPrintf( - "Type: connect\r\n" - "V8-Version: %s\r\n" - "Protocol-Version: 1\r\n" - "Embedding-Host: %s\r\n" - "%s: 0\r\n", - v8::V8::GetVersion(), ATOM_PRODUCT_NAME, kContentLength), true); -} - -// static -void NodeDebugger::DebugMessageHandler(const v8::Debug::Message& message) { - NodeDebugger* self = static_cast( - message.GetIsolate()->GetData(kIsolateSlot)); - - if (self) { - std::string message8(*v8::String::Utf8Value(message.GetJSON())); - self->thread_.message_loop()->PostTask( - FROM_HERE, - base::Bind(&NodeDebugger::SendMessage, self->weak_factory_.GetWeakPtr(), - message8)); - } -} - -void NodeDebugger::DidAccept(net::StreamListenSocket* server, - scoped_ptr socket) { - // Only accept one session. - if (accepted_socket_) { - socket->Send(std::string("Remote debugging session already active"), true); - return; - } - - accepted_socket_ = socket.Pass(); - SendConnectMessage(); -} - -void NodeDebugger::DidRead(net::StreamListenSocket* socket, - const char* data, - int len) { - buffer_.append(data, len); - - do { - if (buffer_.size() == 0) - return; - - // Read the "Content-Length" header. - if (content_length_ < 0) { - size_t pos = buffer_.find("\r\n\r\n"); - if (pos == std::string::npos) - return; - - // We can be sure that the header is "Content-Length: xxx\r\n". - std::string content_length = buffer_.substr(16, pos - 16); - if (!base::StringToInt(content_length, &content_length_)) { - DidClose(accepted_socket_.get()); - return; - } - - // Strip header from buffer. - buffer_ = buffer_.substr(pos + 4); - } - - // Read the message. - if (buffer_.size() >= static_cast(content_length_)) { - std::string message = buffer_.substr(0, content_length_); - buffer_ = buffer_.substr(content_length_); - - OnMessage(message); - - // Get ready for next message. - content_length_ = -1; - } - } while (true); -} - -void NodeDebugger::DidClose(net::StreamListenSocket* socket) { - // If we lost the connection, then simulate a disconnect msg: - OnMessage("{\"seq\":1,\"type\":\"request\",\"command\":\"disconnect\"}"); -} - -} // namespace atom diff --git a/atom/browser/node_debugger.h b/atom/browser/node_debugger.h deleted file mode 100644 index 6ee5b1e20688..000000000000 --- a/atom/browser/node_debugger.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2014 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#ifndef ATOM_BROWSER_NODE_DEBUGGER_H_ -#define ATOM_BROWSER_NODE_DEBUGGER_H_ - -#include - -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/threading/thread.h" -#include "net/socket/stream_listen_socket.h" -#include "v8/include/v8-debug.h" - -namespace atom { - -// Add support for node's "--debug" switch. -class NodeDebugger : public net::StreamListenSocket::Delegate { - public: - explicit NodeDebugger(v8::Isolate* isolate); - virtual ~NodeDebugger(); - - bool IsRunning() const; - - private: - void StartServer(int port); - void CloseSession(); - void OnMessage(const std::string& message); - void SendMessage(const std::string& message); - void SendConnectMessage(); - - static void DebugMessageHandler(const v8::Debug::Message& message); - - // net::StreamListenSocket::Delegate: - void DidAccept(net::StreamListenSocket* server, - scoped_ptr socket) override; - void DidRead(net::StreamListenSocket* socket, - const char* data, - int len) override; - void DidClose(net::StreamListenSocket* socket) override; - - v8::Isolate* isolate_; - - base::Thread thread_; - scoped_ptr server_; - scoped_ptr accepted_socket_; - - std::string buffer_; - int content_length_; - - base::WeakPtrFactory weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(NodeDebugger); -}; - -} // namespace atom - -#endif // ATOM_BROWSER_NODE_DEBUGGER_H_ diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 01df48fdc66c..4a0292e2b51d 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -129,8 +129,7 @@ void NodeBindings::Initialize() { node::g_upstream_node_mode = false; // Init node. - // (we assume it would not node::Init would not modify the parameters under - // embedded mode). + // (we assume node::Init would not modify the parameters under embedded mode). node::Init(nullptr, nullptr, nullptr, nullptr); } @@ -166,7 +165,13 @@ node::Environment* NodeBindings::CreateEnvironment( } void NodeBindings::LoadEnvironment(node::Environment* env) { + if (node::use_debug_agent) + node::StartDebug(env, node::debug_wait_connect); + node::LoadEnvironment(env); + + if (node::use_debug_agent) + node::EnableDebug(env); } void NodeBindings::PrepareMessageLoop() { diff --git a/filenames.gypi b/filenames.gypi index d14c935ab728..586d67c17729 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -148,8 +148,6 @@ 'atom/browser/net/url_request_string_job.h', 'atom/browser/net/url_request_buffer_job.cc', 'atom/browser/net/url_request_buffer_job.h', - 'atom/browser/node_debugger.cc', - 'atom/browser/node_debugger.h', 'atom/browser/ui/accelerator_util.cc', 'atom/browser/ui/accelerator_util.h', 'atom/browser/ui/accelerator_util_mac.mm',