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>
This commit is contained in:
parent
4ddd23f0ec
commit
7954d2a4c7
4
lib/internal/bootstrap_node.js
vendored
4
lib/internal/bootstrap_node.js
vendored
@ -262,7 +262,9 @@
|
|||||||
if (process.inspector) {
|
if (process.inspector) {
|
||||||
inspectorConsole = global.console;
|
inspectorConsole = global.console;
|
||||||
wrapConsoleCall = process.inspector.wrapConsoleCall;
|
wrapConsoleCall = process.inspector.wrapConsoleCall;
|
||||||
delete process.inspector;
|
delete process.inspector.wrapConsoleCall;
|
||||||
|
if (Object.keys(process.inspector).length === 0)
|
||||||
|
delete process.inspector;
|
||||||
}
|
}
|
||||||
var console;
|
var console;
|
||||||
Object.defineProperty(global, 'console', {
|
Object.defineProperty(global, 'console', {
|
||||||
|
@ -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) {
|
Module._resolveFilename = function(request, parent, isMain) {
|
||||||
if (NativeModule.nonInternalExists(request)) {
|
if (NativeModule.nonInternalExists(request)) {
|
||||||
return request;
|
return request;
|
||||||
@ -561,6 +574,7 @@ Module.prototype._compile = function(content, filename) {
|
|||||||
displayErrors: true
|
displayErrors: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var inspectorWrapper = null;
|
||||||
if (process._debugWaitConnect && process._eval == null) {
|
if (process._debugWaitConnect && process._eval == null) {
|
||||||
if (!resolvedArgv) {
|
if (!resolvedArgv) {
|
||||||
// we enter the repl if we're not given a filename argument.
|
// 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
|
// Set breakpoint on module start
|
||||||
if (filename === resolvedArgv) {
|
if (filename === resolvedArgv) {
|
||||||
delete process._debugWaitConnect;
|
delete process._debugWaitConnect;
|
||||||
const Debug = vm.runInDebugContext('Debug');
|
inspectorWrapper = getInspectorCallWrapper();
|
||||||
Debug.setBreakPoint(compiledWrapper, 0, 0);
|
if (!inspectorWrapper) {
|
||||||
|
const Debug = vm.runInDebugContext('Debug');
|
||||||
|
Debug.setBreakPoint(compiledWrapper, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var dirname = path.dirname(filename);
|
var dirname = path.dirname(filename);
|
||||||
var require = internalModule.makeRequireFunction(this);
|
var require = internalModule.makeRequireFunction(this);
|
||||||
var depth = internalModule.requireDepth;
|
var depth = internalModule.requireDepth;
|
||||||
if (depth === 0) stat.cache = new Map();
|
if (depth === 0) stat.cache = new Map();
|
||||||
var result = compiledWrapper.call(this.exports, this.exports, require, this,
|
var result;
|
||||||
filename, dirname);
|
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;
|
if (depth === 0) stat.cache = null;
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
@ -94,7 +94,6 @@ std::unique_ptr<StringBuffer> Utf8ToStringView(const std::string& message) {
|
|||||||
utf16.length());
|
utf16.length());
|
||||||
return StringBuffer::create(view);
|
return StringBuffer::create(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class V8NodeInspector;
|
class V8NodeInspector;
|
||||||
@ -145,6 +144,8 @@ class AgentImpl {
|
|||||||
void FatalException(v8::Local<v8::Value> error,
|
void FatalException(v8::Local<v8::Value> error,
|
||||||
v8::Local<v8::Message> message);
|
v8::Local<v8::Message> message);
|
||||||
|
|
||||||
|
void SchedulePauseOnNextStatement(const std::string& reason);
|
||||||
|
|
||||||
void PostIncomingMessage(InspectorAction action, int session_id,
|
void PostIncomingMessage(InspectorAction action, int session_id,
|
||||||
const std::string& message);
|
const std::string& message);
|
||||||
void ResumeStartup() {
|
void ResumeStartup() {
|
||||||
@ -160,6 +161,8 @@ class AgentImpl {
|
|||||||
static void ThreadCbIO(void* agent);
|
static void ThreadCbIO(void* agent);
|
||||||
static void WriteCbIO(uv_async_t* async);
|
static void WriteCbIO(uv_async_t* async);
|
||||||
static void MainThreadAsyncCb(uv_async_t* req);
|
static void MainThreadAsyncCb(uv_async_t* req);
|
||||||
|
static void CallAndPauseOnStart(
|
||||||
|
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
|
|
||||||
void InstallInspectorOnProcess();
|
void InstallInspectorOnProcess();
|
||||||
|
|
||||||
@ -310,6 +313,14 @@ class V8NodeInspector : public v8_inspector::V8InspectorClient {
|
|||||||
session_->dispatchProtocolMessage(message);
|
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)
|
v8::Local<v8::Context> ensureDefaultContextInGroup(int contextGroupId)
|
||||||
override {
|
override {
|
||||||
return env_->context();
|
return env_->context();
|
||||||
@ -477,6 +488,28 @@ void AgentImpl::InstallInspectorOnProcess() {
|
|||||||
v8::Local<v8::Object> inspector = v8::Object::New(env->isolate());
|
v8::Local<v8::Object> inspector = v8::Object::New(env->isolate());
|
||||||
READONLY_PROPERTY(process, "inspector", inspector);
|
READONLY_PROPERTY(process, "inspector", inspector);
|
||||||
env->SetMethod(inspector, "wrapConsoleCall", InspectorWrapConsoleCall);
|
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) {
|
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);
|
CHECK_EQ(0, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AgentImpl::SchedulePauseOnNextStatement(const std::string& reason) {
|
||||||
|
inspector_->schedulePauseOnNextStatement(reason);
|
||||||
|
}
|
||||||
|
|
||||||
// Exported class Agent
|
// Exported class Agent
|
||||||
Agent::Agent(node::Environment* env) : impl(new AgentImpl(env)) {}
|
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);
|
impl->FatalException(error, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Agent::SchedulePauseOnNextStatement(const std::string& reason) {
|
||||||
|
impl->SchedulePauseOnNextStatement(reason);
|
||||||
|
}
|
||||||
|
|
||||||
InspectorAgentDelegate::InspectorAgentDelegate(AgentImpl* agent,
|
InspectorAgentDelegate::InspectorAgentDelegate(AgentImpl* agent,
|
||||||
const std::string& script_path,
|
const std::string& script_path,
|
||||||
const std::string& script_name,
|
const std::string& script_name,
|
||||||
|
@ -43,6 +43,7 @@ class Agent {
|
|||||||
void WaitForDisconnect();
|
void WaitForDisconnect();
|
||||||
void FatalException(v8::Local<v8::Value> error,
|
void FatalException(v8::Local<v8::Value> error,
|
||||||
v8::Local<v8::Message> message);
|
v8::Local<v8::Message> message);
|
||||||
|
void SchedulePauseOnNextStatement(const std::string& reason);
|
||||||
private:
|
private:
|
||||||
AgentImpl* impl;
|
AgentImpl* impl;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user