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

SEA binary not dying when calling process.exit if a fd is open #57563

Open
Llorx opened this issue Mar 20, 2025 · 1 comment
Open

SEA binary not dying when calling process.exit if a fd is open #57563

Llorx opened this issue Mar 20, 2025 · 1 comment
Labels
single-executable Issues and PRs related to single-executable applications

Comments

@Llorx
Copy link
Contributor

Llorx commented Mar 20, 2025

Version

22.14 and 23.10

Platform

Windows 11 and Debian 11

What steps will reproduce the bug?

Create 2 files:

// parent.js
var spawn = require('child_process').spawn;
var stdio = ["inherit", "inherit", "inherit", "pipe"];
const proc = spawn("child", [], {
    env: process.env,
    stdio: stdio
});
proc.on("error", (e) => {
    console.log("error", e);
});
proc.on("exit", (code) => {
    console.log("exit", code);
});
// child.js
const Fs = require("fs");

console.log("OK!");
const rx = Fs.createReadStream("", {
    fd: 3
});

const onData = () => {};
const onError = (e) => console.error(e);
const onClose = () => {console.log("closed")};

rx.addListener("data", onData);
rx.addListener("error", onError);
rx.addListener("close", onClose);

setTimeout(() => {
    console.log("END!");
    rx.destroy();
    Fs.close(3, console.log);
    process.exit();
}, 2000);

Create a SEA binary from child.js:

{ "main": "child.js", "output": "sea-prep.child.blob" }
node --experimental-sea-config sea-config.child.json
node -e "require('fs').copyFileSync(process.execPath, 'child.exe')"
call npx postject child.exe NODE_SEA_BLOB sea-prep.child.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2

Now run parent.js

node parent.js

You will notice that the child never dies. It will hang forever in the task manager. If instead of SEA you use plain node scripts (and modify parent.js to spawn node child.js) it works as expected.

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior? Why is that the expected behavior?

The child process to exit

What do you see instead?

It hangs forever

Additional information

No response

@lpinca lpinca added the single-executable Issues and PRs related to single-executable applications label Mar 20, 2025
@Llorx
Copy link
Contributor Author

Llorx commented Mar 21, 2025

PS: I have this workaround that works, which follows the nodejs internalities when creating the stdin, but still createReadStream is the way to go I guess as this workaround is not a public API. Still feels weird that createReadStream in non-sea works and sea doesn't.

const rx = new net.Socket({
    fd: 3,
    readable: true,
    writable: false,
    manualStart: true
});
rx._writableState.ended = true;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
single-executable Issues and PRs related to single-executable applications
Projects
None yet
Development

No branches or pull requests

2 participants