diff options
author | Eugene Ostroukhov <eostroukhov@chromium.org> | 2017-03-27 13:11:05 -0700 |
---|---|---|
committer | Eugene Ostroukhov <eostroukhov@chromium.org> | 2017-03-30 13:25:05 -0700 |
commit | 7954d2a4c7f47764643b0941635e093af6170f09 (patch) | |
tree | 2baa58d1b2ad802b08791f57e9cee0ca4c204825 | |
parent | 4ddd23f0ec5202b131b7070d543b20cd031f052a (diff) | |
download | android-node-v8-7954d2a4c7f47764643b0941635e093af6170f09.tar.gz android-node-v8-7954d2a4c7f47764643b0941635e093af6170f09.tar.bz2 android-node-v8-7954d2a4c7f47764643b0941635e093af6170f09.zip |
inspector: use inspector API for "break on start"
This change removes a need for using deprecated debug context for
breaking at the start of the main module.
PR-URL: https://github.com/nodejs/node/pull/12076
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
-rw-r--r-- | lib/internal/bootstrap_node.js | 4 | ||||
-rw-r--r-- | lib/module.js | 31 | ||||
-rw-r--r-- | src/inspector_agent.cc | 43 | ||||
-rw-r--r-- | src/inspector_agent.h | 1 |
4 files changed, 73 insertions, 6 deletions
diff --git a/lib/internal/bootstrap_node.js b/lib/internal/bootstrap_node.js index 479f06e5db..aea83fc331 100644 --- a/lib/internal/bootstrap_node.js +++ b/lib/internal/bootstrap_node.js @@ -262,7 +262,9 @@ if (process.inspector) { inspectorConsole = global.console; wrapConsoleCall = process.inspector.wrapConsoleCall; - delete process.inspector; + delete process.inspector.wrapConsoleCall; + if (Object.keys(process.inspector).length === 0) + delete process.inspector; } var console; Object.defineProperty(global, 'console', { diff --git a/lib/module.js b/lib/module.js index d9442a62b7..fe83cd0ecb 100644 --- a/lib/module.js +++ b/lib/module.js @@ -472,6 +472,19 @@ function tryModuleLoad(module, filename) { } } +function getInspectorCallWrapper() { + var inspector = process.inspector; + if (!inspector || !inspector.callAndPauseOnStart) { + return null; + } + var wrapper = inspector.callAndPauseOnStart.bind(inspector); + delete inspector.callAndPauseOnStart; + if (Object.keys(process.inspector).length === 0) { + delete process.inspector; + } + return wrapper; +} + Module._resolveFilename = function(request, parent, isMain) { if (NativeModule.nonInternalExists(request)) { return request; @@ -561,6 +574,7 @@ Module.prototype._compile = function(content, filename) { displayErrors: true }); + var inspectorWrapper = null; if (process._debugWaitConnect && process._eval == null) { if (!resolvedArgv) { // we enter the repl if we're not given a filename argument. @@ -574,16 +588,25 @@ Module.prototype._compile = function(content, filename) { // Set breakpoint on module start if (filename === resolvedArgv) { delete process._debugWaitConnect; - const Debug = vm.runInDebugContext('Debug'); - Debug.setBreakPoint(compiledWrapper, 0, 0); + inspectorWrapper = getInspectorCallWrapper(); + if (!inspectorWrapper) { + const Debug = vm.runInDebugContext('Debug'); + Debug.setBreakPoint(compiledWrapper, 0, 0); + } } } var dirname = path.dirname(filename); var require = internalModule.makeRequireFunction(this); var depth = internalModule.requireDepth; if (depth === 0) stat.cache = new Map(); - var result = compiledWrapper.call(this.exports, this.exports, require, this, - filename, dirname); + var result; + if (inspectorWrapper) { + result = inspectorWrapper(compiledWrapper, this.exports, this.exports, + require, this, filename, dirname); + } else { + result = compiledWrapper.call(this.exports, this.exports, require, this, + filename, dirname); + } if (depth === 0) stat.cache = null; return result; }; diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc index 1574beb673..34ba5a7fc9 100644 --- a/src/inspector_agent.cc +++ b/src/inspector_agent.cc @@ -94,7 +94,6 @@ std::unique_ptr<StringBuffer> Utf8ToStringView(const std::string& message) { utf16.length()); return StringBuffer::create(view); } - } // namespace class V8NodeInspector; @@ -145,6 +144,8 @@ class AgentImpl { void FatalException(v8::Local<v8::Value> error, v8::Local<v8::Message> message); + void SchedulePauseOnNextStatement(const std::string& reason); + void PostIncomingMessage(InspectorAction action, int session_id, const std::string& message); void ResumeStartup() { @@ -160,6 +161,8 @@ class AgentImpl { static void ThreadCbIO(void* agent); static void WriteCbIO(uv_async_t* async); static void MainThreadAsyncCb(uv_async_t* req); + static void CallAndPauseOnStart( + const v8::FunctionCallbackInfo<v8::Value>& args); void InstallInspectorOnProcess(); @@ -310,6 +313,14 @@ class V8NodeInspector : public v8_inspector::V8InspectorClient { session_->dispatchProtocolMessage(message); } + void schedulePauseOnNextStatement(const std::string& reason) { + if (session_ != nullptr) { + std::unique_ptr<StringBuffer> buffer = Utf8ToStringView(reason); + session_->schedulePauseOnNextStatement(buffer->string(), + buffer->string()); + } + } + v8::Local<v8::Context> ensureDefaultContextInGroup(int contextGroupId) override { return env_->context(); @@ -477,6 +488,28 @@ void AgentImpl::InstallInspectorOnProcess() { v8::Local<v8::Object> inspector = v8::Object::New(env->isolate()); READONLY_PROPERTY(process, "inspector", inspector); env->SetMethod(inspector, "wrapConsoleCall", InspectorWrapConsoleCall); + if (options_.wait_for_connect()) { + env->SetMethod(inspector, "callAndPauseOnStart", CallAndPauseOnStart); + } +} + +// static +void AgentImpl::CallAndPauseOnStart( + const v8::FunctionCallbackInfo<v8::Value>& args) { + Environment* env = Environment::GetCurrent(args); + CHECK_GT(args.Length(), 1); + CHECK(args[0]->IsFunction()); + std::vector<v8::Local<v8::Value>> call_args; + for (int i = 2; i < args.Length(); i++) { + call_args.push_back(args[i]); + } + + env->inspector_agent()->SchedulePauseOnNextStatement("Break on start"); + + v8::MaybeLocal<v8::Value> retval = + args[0].As<v8::Function>()->Call(env->context(), args[1], + call_args.size(), call_args.data()); + args.GetReturnValue().Set(retval.ToLocalChecked()); } std::unique_ptr<StringBuffer> ToProtocolString(v8::Local<v8::Value> value) { @@ -682,6 +715,10 @@ void AgentImpl::Write(TransportAction action, int session_id, CHECK_EQ(0, err); } +void AgentImpl::SchedulePauseOnNextStatement(const std::string& reason) { + inspector_->schedulePauseOnNextStatement(reason); +} + // Exported class Agent Agent::Agent(node::Environment* env) : impl(new AgentImpl(env)) {} @@ -715,6 +752,10 @@ void Agent::FatalException(v8::Local<v8::Value> error, impl->FatalException(error, message); } +void Agent::SchedulePauseOnNextStatement(const std::string& reason) { + impl->SchedulePauseOnNextStatement(reason); +} + InspectorAgentDelegate::InspectorAgentDelegate(AgentImpl* agent, const std::string& script_path, const std::string& script_name, diff --git a/src/inspector_agent.h b/src/inspector_agent.h index 9cc2fa676d..50575d7c28 100644 --- a/src/inspector_agent.h +++ b/src/inspector_agent.h @@ -43,6 +43,7 @@ class Agent { void WaitForDisconnect(); void FatalException(v8::Local<v8::Value> error, v8::Local<v8::Message> message); + void SchedulePauseOnNextStatement(const std::string& reason); private: AgentImpl* impl; }; |