Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
'v8_embedder_string': '-node.32',
'v8_embedder_string': '-node.33',

##### V8 defaults for Node.js #####

Expand Down
1 change: 1 addition & 0 deletions deps/v8/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ Sergey Markelov <sergionso@gmail.com>
Shawn Anastasio <shawnanastasio@gmail.com>
Shawn Presser <shawnpresser@gmail.com>
Sho Miyamoto <me@shqld.dev>
Shumaf Lovpache <soarex16@gmail.com>
Stefan Penner <stefan.penner@gmail.com>
Stefan Stojanovic <stefko.stojanovic@gmail.com>
Stephan Hartmann <stha09@googlemail.com>
Expand Down
8 changes: 7 additions & 1 deletion deps/v8/src/debug/debug-interface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,13 @@ bool Script::SetInstrumentationBreakpoint(BreakpointId* id) const {
i::SharedFunctionInfo::ScriptIterator it(isolate, *script);
for (i::Tagged<i::SharedFunctionInfo> sfi = it.Next(); !sfi.is_null();
sfi = it.Next()) {
if (sfi->is_toplevel()) {
// Node.js compiles CJS modules via ScriptCompiler::CompileFunction so that
// module-local bindings like __filename can be injected as function
// parameters without leaking into the global scope. The resulting Script
// carries two SFIs: a synthetic toplevel that just returns the wrapped
// function, and the wrapped SFI that the embedder actually invokes. For
// such scripts we should pick the wrapped SFI.
if (script->is_wrapped() ? sfi->is_wrapped() : sfi->is_toplevel()) {
return isolate->debug()->SetBreakpointForFunction(
handle(sfi, isolate), isolate->factory()->empty_string(), id,
internal::Debug::kInstrumentation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,37 @@ remove breakpoint..
evaluate script without sourceMappingURL..
evaluate script with sourceMappingURL..

Running test: testWrappedScriptInstrumentation
set breakpoint and run wrapped script..
paused with reason: instrumentation
{
scriptId : <scriptId>
url : cjs-module.js
}
remove breakpoint..
{
id : <messageId>
result : {
}
}

Running test: testWrappedScriptWithSourceMap
set breakpoint for scriptWithSourceMapParsed..
run wrapped script without sourceMappingURL..
run wrapped script with sourceMappingURL..
paused with reason: instrumentation
{
scriptId : <scriptId>
sourceMapURL : cjs.js.map
url : cjs-sourcemapped.js
}
remove breakpoint..
{
id : <messageId>
result : {
}
}

Running test: testBlackboxing
set breakpoint and evaluate blackboxed script..
evaluate not blackboxed script..
Expand Down
42 changes: 42 additions & 0 deletions deps/v8/test/inspector/debugger/set-instrumentation-breakpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,48 @@ InspectorTest.runAsyncTestSuite([
await Protocol.Debugger.disable();
},

async function testWrappedScriptInstrumentation() {
await Protocol.Debugger.enable();
InspectorTest.log('set breakpoint and run wrapped script..');
const { result : firstResult } = await Protocol.Debugger.setInstrumentationBreakpoint({
instrumentation: 'beforeScriptExecution'
});
utils.compileAndRunWrapped(contextGroup.id, '1 + 2', 'cjs-module.js');
{
const { params: { reason, data } } = await Protocol.Debugger.oncePaused();
InspectorTest.log(`paused with reason: ${reason}`);
InspectorTest.logMessage(data);
}
await Protocol.Debugger.resume();
InspectorTest.log('remove breakpoint..');
InspectorTest.logMessage(await Protocol.Debugger.removeBreakpoint({
breakpointId: firstResult.breakpointId
}));
await Protocol.Debugger.disable();
},

async function testWrappedScriptWithSourceMap() {
await Protocol.Debugger.enable();
InspectorTest.log('set breakpoint for scriptWithSourceMapParsed..');
const { result : firstResult } = await Protocol.Debugger.setInstrumentationBreakpoint({
instrumentation: 'beforeScriptWithSourceMapExecution'
});
InspectorTest.log('run wrapped script without sourceMappingURL..');
utils.compileAndRunWrapped(contextGroup.id, '1 + 2', 'cjs-plain.js');
InspectorTest.log('run wrapped script with sourceMappingURL..');
utils.compileAndRunWrapped(contextGroup.id, '1 + 2\n//# sourceMappingURL=cjs.js.map', 'cjs-sourcemapped.js');
{
const { params: { reason, data } } = await Protocol.Debugger.oncePaused();
InspectorTest.log(`paused with reason: ${reason}`);
InspectorTest.logMessage(data);
}
InspectorTest.log('remove breakpoint..');
InspectorTest.logMessage(await Protocol.Debugger.removeBreakpoint({
breakpointId: firstResult.breakpointId
}));
await Protocol.Debugger.disable();
},

async function testBlackboxing() {
await Protocol.Debugger.enable();
await Protocol.Debugger.setBlackboxPatterns({patterns: ['foo\.js']});
Expand Down
17 changes: 17 additions & 0 deletions deps/v8/test/inspector/inspector-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ class UtilsExtension : public InspectorIsolateData::SetupGlobalTask {
utils->Set(isolate, "compileAndRunWithOrigin",
v8::FunctionTemplate::New(
isolate, &UtilsExtension::CompileAndRunWithOrigin));
utils->Set(isolate, "compileAndRunWrapped",
v8::FunctionTemplate::New(
isolate, &UtilsExtension::CompileAndRunWrapped));
utils->Set(isolate, "setCurrentTimeMSForTest",
v8::FunctionTemplate::New(
isolate, &UtilsExtension::SetCurrentTimeMSForTest));
Expand Down Expand Up @@ -233,6 +236,20 @@ class UtilsExtension : public InspectorIsolateData::SetupGlobalTask {
info[4].As<v8::Int32>(), info[5].As<v8::Boolean>()));
}

static void CompileAndRunWrapped(
const v8::FunctionCallbackInfo<v8::Value>& info) {
if (info.Length() != 3 || !info[0]->IsInt32() || !info[1]->IsString() ||
!info[2]->IsString()) {
FATAL(
"Internal error: compileAndRunWrapped(context_group_id, source, "
"url).");
}
backend_runner_->Append(std::make_unique<ExecuteWrappedStringTask>(
info.GetIsolate(), info[0].As<v8::Int32>()->Value(),
ToVector(info.GetIsolate(), info[1].As<v8::String>()),
info[2].As<v8::String>()));
}

static void SetCurrentTimeMSForTest(
const v8::FunctionCallbackInfo<v8::Value>& info) {
if (info.Length() != 1 || !info[0]->IsNumber()) {
Expand Down
19 changes: 19 additions & 0 deletions deps/v8/test/inspector/tasks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,24 @@ void ExecuteStringTask::Run(InspectorIsolateData* data) {
}
}

void ExecuteWrappedStringTask::Run(InspectorIsolateData* data) {
v8::HandleScope handle_scope(data->isolate());
v8::Local<v8::Context> context = data->GetDefaultContext(context_group_id_);
v8::MicrotasksScope microtasks_scope(context,
v8::MicrotasksScope::kRunMicrotasks);
v8::Context::Scope context_scope(context);
v8::ScriptOrigin origin(ToV8String(data->isolate(), name_));
v8::Local<v8::String> source = ToV8String(data->isolate(), expression_);
v8::ScriptCompiler::Source scriptSource(source, origin);
v8::Local<v8::Function> function;
if (!v8::ScriptCompiler::CompileFunction(context, &scriptSource)
.ToLocal(&function)) {
return;
}
v8::MaybeLocal<v8::Value> result =
function->Call(context, context->Global(), 0, nullptr);
USE(result);
}

} // namespace internal
} // namespace v8
21 changes: 21 additions & 0 deletions deps/v8/test/inspector/tasks.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,27 @@ class ExecuteStringTask : public TaskRunner::Task {
int context_group_id_;
};

class ExecuteWrappedStringTask : public TaskRunner::Task {
public:
ExecuteWrappedStringTask(v8::Isolate* isolate, int context_group_id,
const std::vector<uint16_t>& expression,
v8::Local<v8::String> name)
: expression_(expression),
name_(ToVector(isolate, name)),
context_group_id_(context_group_id) {}

~ExecuteWrappedStringTask() override = default;
ExecuteWrappedStringTask(const ExecuteWrappedStringTask&) = delete;
ExecuteWrappedStringTask& operator=(const ExecuteWrappedStringTask&) = delete;
bool is_priority_task() override { return false; }
void Run(InspectorIsolateData* data) override;

private:
std::vector<uint16_t> expression_;
std::vector<uint16_t> name_;
int context_group_id_;
};

class SetTimeoutTask : public TaskRunner::Task {
public:
SetTimeoutTask(int context_group_id, v8::Isolate* isolate,
Expand Down
54 changes: 0 additions & 54 deletions test/known_issues/test-inspector-instrumentation-breakpoint.js

This file was deleted.

59 changes: 59 additions & 0 deletions test/parallel/test-inspector-instrumentation-breakpoint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use strict';

const common = require('../common');
common.skipIfInspectorDisabled();

const assert = require('node:assert/strict');

const fixtures = require('../common/fixtures');
const { NodeInstance } = require('../common/inspector-helper');

async function testBreakpointBeforeScriptExecution(session) {
console.log(
'[test]',
'Verifying debugger stops on start of each script ' +
'(Debugger.setInstrumentationBreakpoint with beforeScriptExecution)',
);

const commands = [
{ method: 'Runtime.enable' },
{ method: 'Debugger.enable' },
{
method: 'Debugger.setInstrumentationBreakpoint',
params: { instrumentation: 'beforeScriptExecution' },
},
{ method: 'Runtime.runIfWaitingForDebugger' },
];

await session.send(commands);

const mainURL = new URL('main.js', session.scriptURL()).href;

// Break on start.
await session.waitForBreakOnLine(3, 'node:internal/main/run_main_module');
await session.send([{ method: 'Debugger.resume' }]);

// Script loaded.
await session.waitForBreakOnLine(0, mainURL);
await session.send([{ method: 'Debugger.resume' }]);

// Dependency loaded.
await session.waitForBreakOnLine(0, mainURL);
}

async function runTest() {
const main = fixtures.path(
'inspector-instrumentation-breakpoint',
'main.js',
);

const child = new NodeInstance(['--inspect-brk=0'], '', main);
const session = await child.connectInspectorSession();

await testBreakpointBeforeScriptExecution(session);
await session.runToCompletion();

assert.strictEqual((await child.expectShutdown()).exitCode, 0);
}

runTest();
Loading