Improve JavaScript debugging in d8

Adds ability to pause JavaScript debugger from d8 by defining a global function
`handleInspectorMessage` which should block waiting for a new inspector message,
and `send` it afterwards.

Additionally, adds a simple helper script that, when invoked via `websocketd`
as per instructions, can be used for debugging `d8` using Chrome DevTools
(inspecting script sources, pausing, stepping over, etc.).

Change-Id: Iee75fb4e3f2ccc8c8552c804fefaefb233d6b089
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1829221
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Ingvar Stepanyan <rreverser@google.com>
Cr-Commit-Position: refs/heads/master@{#64040}
This commit is contained in:
Ingvar Stepanyan 2019-09-27 19:07:58 +01:00 committed by Commit Bot
parent b6c625f3b0
commit 36ab7afb9e
2 changed files with 58 additions and 0 deletions

View File

@ -2502,6 +2502,33 @@ class InspectorClient : public v8_inspector::V8InspectorClient {
context_.Reset(isolate_, context);
}
void runMessageLoopOnPause(int contextGroupId) override {
v8::Isolate::AllowJavascriptExecutionScope allow_script(isolate_);
v8::HandleScope handle_scope(isolate_);
Local<String> callback_name =
v8::String::NewFromUtf8(isolate_, "handleInspectorMessage",
v8::NewStringType::kNormal)
.ToLocalChecked();
Local<Context> context = context_.Get(isolate_);
Local<Value> callback =
context->Global()->Get(context, callback_name).ToLocalChecked();
if (!callback->IsFunction()) return;
v8::TryCatch try_catch(isolate_);
is_paused = true;
while (is_paused) {
USE(Local<Function>::Cast(callback)->Call(context, Undefined(isolate_), 0,
{}));
if (try_catch.HasCaught()) {
Shell::ReportException(isolate_, &try_catch);
is_paused = false;
}
}
}
void quitMessageLoopOnPause() override { is_paused = false; }
private:
static v8_inspector::V8InspectorSession* GetSession(Local<Context> context) {
InspectorClient* inspector_client = static_cast<InspectorClient*>(
@ -2540,6 +2567,7 @@ class InspectorClient : public v8_inspector::V8InspectorClient {
std::unique_ptr<v8_inspector::V8Inspector> inspector_;
std::unique_ptr<v8_inspector::V8InspectorSession> session_;
std::unique_ptr<v8_inspector::V8Inspector::Channel> channel_;
bool is_paused = false;
Global<Context> context_;
Isolate* isolate_;
};

30
tools/inspect-d8.js Normal file
View File

@ -0,0 +1,30 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This helper allows to debug d8 using Chrome DevTools.
//
// It runs a simple REPL for inspector messages and relies on
// websocketd (https://github.com/joewalnes/websocketd) for the WebSocket
// communication.
//
// You can start a session with a debug build of d8 like:
//
// $ websocketd out/x64.debug/d8 YOUR_SCRIPT.js tools/inspect-d8.js
//
// After that, copy the URL from console and pass it as `ws=` parameter to
// the Chrome DevTools frontend like:
//
// chrome-devtools://devtools/bundled/js_app.html?ws=localhost:80
function receive(msg) {
print(msg);
}
function handleInspectorMessage() {
send(readline());
}
while (true) {
handleInspectorMessage();
}