Closed
Description
Version
- v17.1.0
- v18.14.2
- v19.9.0
Platform
Linux WORKSTATION 5.15.90.1-microsoft-standard-WSL2 #1 SMP Fri Jan 27 02:56:13 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Microsoft Windows NT 10.0.19045.0 x64
Subsystem
vm, maybe node:internal/per_context
What steps will reproduce the bug?
- Create a
MessagePort
- Create a
Worker
and transfer the message port to the worker. - Create a VM context and contextify the message port
- (Sometimes) Attempt to access the contextified message port
Sample code to reproduce
/* eslint-disable */
const { Worker } = require('node:worker_threads');
const messageChannel = new MessageChannel();
const text = `
const vm = require('node:vm');
const {
isMainThread,
moveMessagePortToContext,
workerData,
} = require('node:worker_threads');
const context = Object.create(null);
context.console = console;
vm.createContext(context, {
codeGeneration: {
strings: false,
wasm: false,
},
});
console.log('[WT] messagePort ctor:', workerData.messagePort.constructor.name);
const messageChannel = new MessageChannel();
messageChannel.port1.onmessage = (ev) => {
console.log('[WT] RECV MSG', ev.data);
messageChannel.port1.close();
};
context.messagePort = moveMessagePortToContext(
workerData.crash ? workerData.messagePort : messageChannel.port2,
context,
);
// This vm.runInContext doesn't seem entirely necessary to trigger the crash
// Sometimes just accessing the properties of 'messagePort' is required
vm.runInContext(
\`
console.log("[VM] Started");
messagePort.postMessage("Hello, World!")
\`,
context,
{ displayErrors: true }
);
`;
// Change this to false to avoid crashing
// NOTE: Just transferring the MessagePort to the worker,
// without contextifying, or even using it from the worker
// does NOT trigger a crash and works as expected.
const crash = true;
new Worker(text, {
workerData: {
crash,
messagePort: messageChannel.port2,
},
env: Object.create(null),
eval: true,
transferList: [messageChannel.port2],
});
if (crash) {
messageChannel.port1.onmessage = (ev) => {
console.log('[MAIN] RECV MSG', ev.data);
messageChannel.port1.close();
};
}
How often does it reproduce? Is there a required condition?
It always reproduces. It sometimes (on Node 18 on Windows, apparently) requires accessing a property in the contextified port. Otherwise just contextifying the port is enough.
What is the expected behavior? Why is that the expected behavior?
The port is contextified and usable, even across multiple contexts. At worst, an error should occur without crashing or aborting the Node process.
What do you see instead?
Node crashes with a segmentation fault.
Sample output (Node 17)
[WT] messagePort ctor: MessagePort
[MAIN] RECV MSG Hello, World!
[VM] Started
Command terminated by signal 11
Sample output (Node 18)
[WT] messagePort ctor: MessagePort
Sample output (Node 19)
[WT] messagePort ctor: MessagePort
[MAIN] RECV MSG Hello, World!
[VM] Started
[1] 4551 segmentation fault node sample.js
Additional information
No response