Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bootstrap: clean up inspector console methods during serialization #44279

Merged
merged 1 commit into from Sep 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 27 additions & 0 deletions lib/internal/console/constructor.js
Expand Up @@ -28,6 +28,7 @@ const {
SafeArrayIterator,
SafeMap,
SafeWeakMap,
SafeSet,
StringPrototypeIncludes,
StringPrototypePadStart,
StringPrototypeRepeat,
Expand Down Expand Up @@ -687,6 +688,32 @@ Console.prototype.groupCollapsed = Console.prototype.group;
function initializeGlobalConsole(globalConsole) {
globalConsole[kBindStreamsLazy](process);
globalConsole[kBindProperties](true, 'auto');

const {
addSerializeCallback,
isBuildingSnapshot,
} = require('v8').startupSnapshot;

if (!internalBinding('config').hasInspector || !isBuildingSnapshot()) {
return;
}
const { console: consoleFromVM } = internalBinding('inspector');
const nodeConsoleKeys = ObjectKeys(Console.prototype);
const vmConsoleKeys = ObjectKeys(consoleFromVM);
const originalKeys = new SafeSet(vmConsoleKeys.concat(nodeConsoleKeys));
const inspectorConsoleKeys = new SafeSet();
for (const key of ObjectKeys(globalConsole)) {
if (!originalKeys.has(key)) {
inspectorConsoleKeys.add(key);
}
}
// During deserialization these should be reinstalled to console by
// V8 when the inspector client is created.
addSerializeCallback(() => {
for (const key of inspectorConsoleKeys) {
globalConsole[key] = undefined;
}
});
}

module.exports = {
Expand Down
9 changes: 9 additions & 0 deletions test/fixtures/snapshot/console.js
@@ -0,0 +1,9 @@
const {
setDeserializeMainFunction,
} = require('v8').startupSnapshot;

console.log(JSON.stringify(Object.keys(console), null, 2));

setDeserializeMainFunction(() => {
console.log(JSON.stringify(Object.keys(console), null, 2));
});
62 changes: 62 additions & 0 deletions test/parallel/test-snapshot-console.js
@@ -0,0 +1,62 @@
'use strict';

// TODO(joyeecheung): remove the flag when it is turned on by default in V8.
// Flags: --experimental-async-stack-tagging-api
// This tests the console works in the deserialized snapshot.

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

const assert = require('assert');
const { spawnSync } = require('child_process');
const tmpdir = require('../common/tmpdir');
const fixtures = require('../common/fixtures');
const path = require('path');
const fs = require('fs');

tmpdir.refresh();
const blobPath = path.join(tmpdir.path, 'snapshot.blob');
const entry = fixtures.path('snapshot', 'console.js');

{
const child = spawnSync(process.execPath, [
'--experimental-async-stack-tagging-api',
'--snapshot-blob',
blobPath,
'--build-snapshot',
entry,
], {
cwd: tmpdir.path
});
const stdout = child.stdout.toString();
if (child.status !== 0) {
console.log(stdout);
console.log(child.stderr.toString());
assert.strictEqual(child.status, 0);
}
assert.deepStrictEqual(Object.keys(console), JSON.parse(stdout));
const stats = fs.statSync(path.join(tmpdir.path, 'snapshot.blob'));
assert(stats.isFile());
}

{
const child = spawnSync(process.execPath, [
'--experimental-async-stack-tagging-api',
'--snapshot-blob',
blobPath,
], {
cwd: tmpdir.path,
env: {
...process.env,
}
});

const stdout = child.stdout.toString();
if (child.status !== 0) {
console.log(stdout);
console.log(child.stderr.toString());
assert.strictEqual(child.status, 0);
}
assert.deepStrictEqual(Object.keys(console), JSON.parse(stdout));
assert.strictEqual(child.status, 0);
}