Created
May 25, 2022 12:57
-
-
Save sapphi-red/a0179b52ebd3b6a19f51743594810ecf to your computer and use it in GitHub Desktop.
Node.js eval worker Segmentation fault reproduction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Worker } from 'worker_threads' | |
function genWorkerCode(fn) { | |
return ` | |
const doWork = ${fn.toString()} | |
const { parentPort } = require('worker_threads') | |
parentPort.on('message', async (args) => { | |
const res = await doWork(...args) | |
parentPort.postMessage(res) | |
}) | |
` | |
} | |
// 10s after. 0-9s works well | |
const startAt = Date.now() + 10 * 1000 | |
const fn = async (_startAt) => { | |
const until = new Date(_startAt).valueOf() - Date.now() | |
await new Promise((resolve) => setTimeout(resolve, until)) | |
import('worker_threads') // fails | |
// require('worker_threads') // success | |
} | |
// same behavior when fn is string | |
/* | |
const fn = `async (_startAt) => { | |
const until = new Date(_startAt).valueOf() - Date.now() | |
await new Promise((resolve) => setTimeout(resolve, until)) | |
import('worker_threads') // fails | |
// require('worker_threads') // success | |
} | |
` | |
*/ | |
const code = genWorkerCode(fn) | |
const worker = new Worker(code, { eval: true }) | |
worker.on('message', (res) => { | |
console.log('done', res) | |
worker.unref() | |
}) | |
worker.on('error', (err) => { | |
console.error('error', err) | |
worker.unref() | |
}) | |
worker.on('exit', (code) => { | |
console.log('exit', code) | |
}) | |
worker.postMessage([startAt]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { Worker } = require('worker_threads') | |
function genWorkerCode(fn) { | |
return ` | |
const doWork = ${fn.toString()} | |
const { parentPort } = require('worker_threads') | |
parentPort.on('message', async (args) => { | |
const res = await doWork(...args) | |
parentPort.postMessage(res) | |
}) | |
` | |
} | |
// 10s after. 0-9s works well | |
const startAt = Date.now() + 10 * 1000 | |
const fn = async (_startAt) => { | |
const until = new Date(_startAt).valueOf() - Date.now() | |
await new Promise((resolve) => setTimeout(resolve, until)) | |
import('worker_threads') // fails | |
// require('worker_threads') // success | |
} | |
// same behavior when fn is string | |
/* | |
const fn = `async (_startAt) => { | |
const until = new Date(_startAt).valueOf() - Date.now() | |
await new Promise((resolve) => setTimeout(resolve, until)) | |
import('worker_threads') // fails | |
// require('worker_threads') // success | |
} | |
` | |
*/ | |
const code = genWorkerCode(fn) | |
const worker = new Worker(code, { eval: true }) | |
worker.on('message', (res) => { | |
console.log('done', res) | |
worker.unref() | |
}) | |
worker.on('error', (err) => { | |
console.error('error', err) | |
worker.unref() | |
}) | |
worker.on('exit', (code) => { | |
console.log('exit', code) | |
}) | |
worker.postMessage([startAt]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Worker } from 'worker_threads' | |
// 10s after. | |
const startAt = Date.now() + 10 * 1000 | |
const worker = new Worker('./worker.js') | |
worker.on('message', (res) => { | |
console.log('done', res) | |
worker.unref() | |
}) | |
worker.on('error', (err) => { | |
console.error('error', err) | |
worker.unref() | |
}) | |
worker.on('exit', (code) => { | |
console.log('exit', code) | |
}) | |
worker.postMessage([startAt]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Worker } from 'worker_threads' | |
// 10s after. | |
const startAt = Date.now() + 10 * 1000 | |
const worker = new Worker('./workerm.mjs') | |
worker.on('message', (res) => { | |
console.log('done', res) | |
worker.unref() | |
}) | |
worker.on('error', (err) => { | |
console.error('error', err) | |
worker.unref() | |
}) | |
worker.on('exit', (code) => { | |
console.log('exit', code) | |
}) | |
worker.postMessage([startAt]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "po", | |
"version": "1.0.0", | |
"description": "", | |
"author": "sapphi-red" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const doWork = async (_startAt) => { | |
const until = new Date(_startAt).valueOf() - Date.now() | |
await new Promise((resolve) => setTimeout(resolve, until)) | |
import('worker_threads') // success | |
// require('worker_threads') // success | |
} | |
const { parentPort } = require('worker_threads') | |
parentPort.on('message', async (args) => { | |
const res = await doWork(...args) | |
parentPort.postMessage(res) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { parentPort } from 'worker_threads' | |
const doWork = async (_startAt) => { | |
const until = new Date(_startAt).valueOf() - Date.now() | |
await new Promise((resolve) => setTimeout(resolve, until)) | |
import('worker_threads') // success | |
} | |
parentPort.on('message', async (args) => { | |
const res = await doWork(...args) | |
parentPort.postMessage(res) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment