bootstrap: clean up inspector console methods during serialization
Some console methods are created by the V8 inspector after an inspector client is created, reset them to undefined during sereialization to avoid holding on to invalid references in the snapshot. V8 will take care of the re-initialization when another inspector client is created during deserialization. PR-URL: https://github.com/nodejs/node/pull/44279 Fixes: https://github.com/nodejs/node-v8/issues/237 Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
parent
bae03c4e30
commit
f0cf1005a3
@ -28,6 +28,7 @@ const {
|
||||
SafeArrayIterator,
|
||||
SafeMap,
|
||||
SafeWeakMap,
|
||||
SafeSet,
|
||||
StringPrototypeIncludes,
|
||||
StringPrototypePadStart,
|
||||
StringPrototypeRepeat,
|
||||
@ -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 = {
|
||||
|
9
test/fixtures/snapshot/console.js
vendored
Normal file
9
test/fixtures/snapshot/console.js
vendored
Normal file
@ -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
test/parallel/test-snapshot-console.js
Normal file
62
test/parallel/test-snapshot-console.js
Normal file
@ -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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user