summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Ostroukhov <eostroukhov@chromium.org>2017-03-27 13:11:05 -0700
committerEugene Ostroukhov <eostroukhov@chromium.org>2017-03-30 13:25:05 -0700
commit7954d2a4c7f47764643b0941635e093af6170f09 (patch)
tree2baa58d1b2ad802b08791f57e9cee0ca4c204825
parent4ddd23f0ec5202b131b7070d543b20cd031f052a (diff)
downloadandroid-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.js4
-rw-r--r--lib/module.js31
-rw-r--r--src/inspector_agent.cc43
-rw-r--r--src/inspector_agent.h1
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;
};