diff --git a/atom.gyp b/atom.gyp index 44e5e3e8b48f..3a5dc579b99e 100644 --- a/atom.gyp +++ b/atom.gyp @@ -121,6 +121,8 @@ 'atom/browser/net/atom_url_request_job_factory.h', 'atom/browser/net/url_request_string_job.cc', 'atom/browser/net/url_request_string_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', diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index d507e40c8a89..af63aad23a88 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -8,6 +8,7 @@ #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" @@ -57,6 +58,9 @@ void AtomBrowserMainParts::PostEarlyInitialization() { node_bindings_->Initialize(); + // Support the "--debug" switch. + node_debugger_.reset(new NodeDebugger); + // Create the global environment. global_env = node_bindings_->CreateEnvironment(js_env_->context()); diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index 269e042b3768..a221ea62cd7b 100644 --- a/atom/browser/atom_browser_main_parts.h +++ b/atom/browser/atom_browser_main_parts.h @@ -13,6 +13,7 @@ class AtomBindings; class Browser; class JavascriptEnvironment; class NodeBindings; +class NodeDebugger; class AtomBrowserMainParts : public brightray::BrowserMainParts { public: @@ -40,6 +41,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { scoped_ptr js_env_; scoped_ptr node_bindings_; scoped_ptr atom_bindings_; + scoped_ptr node_debugger_; static AtomBrowserMainParts* self_; diff --git a/atom/browser/node_debugger.cc b/atom/browser/node_debugger.cc new file mode 100644 index 000000000000..f66a2d063896 --- /dev/null +++ b/atom/browser/node_debugger.cc @@ -0,0 +1,67 @@ +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// 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 "atom/common/atom_version.h" +#include "base/command_line.h" +#include "base/strings/string_number_conversions.h" +#include "v8/include/v8.h" +#include "v8/include/v8-debug.h" + +#include "atom/common/node_includes.h" + +namespace atom { + +// static +uv_async_t NodeDebugger::dispatch_debug_messages_async_; + +NodeDebugger::NodeDebugger() { + uv_async_init(uv_default_loop(), + &dispatch_debug_messages_async_, + DispatchDebugMessagesInMainThread); + uv_unref(reinterpret_cast(&dispatch_debug_messages_async_)); + + 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); + v8::Debug::EnableAgent("atom-shell " ATOM_VERSION, port, + wait_for_connection); + v8::Debug::SetDebugMessageDispatchHandler(DispatchDebugMessagesInMsgThread, + false); + } +} + +NodeDebugger::~NodeDebugger() { +} + +// static +void NodeDebugger::DispatchDebugMessagesInMainThread(uv_async_t* handle) { + v8::Debug::ProcessDebugMessages(); +} + +// static +void NodeDebugger::DispatchDebugMessagesInMsgThread() { + uv_async_send(&dispatch_debug_messages_async_); +} + +} // namespace atom diff --git a/atom/browser/node_debugger.h b/atom/browser/node_debugger.h new file mode 100644 index 000000000000..4dfdced8ee9d --- /dev/null +++ b/atom/browser/node_debugger.h @@ -0,0 +1,30 @@ +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// 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 "base/basictypes.h" +#include "vendor/node/deps/uv/include/uv.h" + +namespace atom { + +// Add support for node's "--debug" switch. +class NodeDebugger { + public: + NodeDebugger(); + virtual ~NodeDebugger(); + + private: + static void DispatchDebugMessagesInMainThread(uv_async_t* handle); + static void DispatchDebugMessagesInMsgThread(); + + static uv_async_t dispatch_debug_messages_async_; + + DISALLOW_COPY_AND_ASSIGN(NodeDebugger); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_NODE_DEBUGGER_H_ diff --git a/docs/README.md b/docs/README.md index 6d2ec76a73db..aaf27d6d95a9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,6 +3,7 @@ * [Quick start](tutorial/quick-start.md) * [Application distribution](tutorial/application-distribution.md) * [Use native node modules](tutorial/use-native-node-modules.md) +* [Debugging browser process](tutorial/debugging-browser-process.md) ## API references diff --git a/docs/tutorial/debugging-browser-process.md b/docs/tutorial/debugging-browser-process.md new file mode 100644 index 000000000000..34957312b0d3 --- /dev/null +++ b/docs/tutorial/debugging-browser-process.md @@ -0,0 +1,49 @@ +# Debugging browser process + +The devtools of browser window can only debug the scripts of the web pages +(e.g. the renderer process), in order to provide a way to debug the scripts of +the browser side (e.g. the browser process), atom-shell has provided the +`--debug` and `--debug-brk` switches. + +## Command line switches + +### `--debug=[port]` + +When this switch is used atom-shell would listen for V8 debugger protocol on +`port`, the `port` is `5858` by default. + +### `debug-brk=[port]` + +Like `--debug` but pauses the script on the first line. + +## Use node-inspector for debugging + +__Note:__ Atom Shell uses node v0.11.13, which currently doesn't work very well +with node-inspector, and the browser process would crash if you inspect the +`process` object under node-inspector's console. + +### 1. Start the [node-inspector](node-inspector) server + +```bash +$ node-inspector +``` + +### 2. Enable debug mode for atom-shell + +You can either start atom-shell with a debug flag like: + +```bash +$ atom-shell --debug your/app +``` + +or, to pause your script on the first line: + +```bash +$ atom-shell --debug-brk your/app +``` + +### 3. Load the debugger UI + +Open http://127.0.0.1:8080/debug?port=5858 in the Chrome browser. + +[node-inspector](https://github.com/node-inspector/node-inspector)