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

Forked child process not detaching on windows #5146

Closed
filmerjarred opened this issue Feb 8, 2016 · 11 comments
Closed

Forked child process not detaching on windows #5146

filmerjarred opened this issue Feb 8, 2016 · 11 comments
Labels
child_process Issues and PRs related to the child_process subsystem. windows Issues and PRs related to the Windows platform.

Comments

@filmerjarred
Copy link

As far as I can tell the expected default behavior of a child process created with child_process.fork, is to be able to run independently of the process that spawned it once the parent dies.

//parent.js
var child_process = require("child_process");

var p = child_process.fork("child.js")
p.disconnect();
p.unref();

process.exit()
//child.js
setTimeout(function(){
    console.log(1);
}, 1000000);

So if parents.js is executed, child.js should remain as an orphaned process after the parent exits. This works on Linux, but not on Windows.

Tested on Ubuntu 14.04.3 LTS and Windows 8.1
Using Node v5.5.0 and v0.10.25 (both tested on each platform)

@mscdex mscdex added child_process Issues and PRs related to the child_process subsystem. windows Issues and PRs related to the Windows platform. labels Feb 9, 2016
@bnoordhuis
Copy link
Member

As far as I can tell the expected default behavior of a child process created with child_process.fork, is to be able to run independently of the process that spawned it once the parent dies.

The documentation indeed uses the word "independent" but the intent is convey that the processes are independent instances of the runtime, not that they're exempt from normal process control. /cc @nodejs/documentation - that should probably be cleared up.

On Windows, the child processes that node spawns are part of the same process group unless { detached: true } is passed to child_process.spawn().

In detached mode, the child process is created with the CREATE_NEW_PROCESS_GROUP and DETACHED_PROCESS flags set. See the documentation for the detached option for a list of caveats.

@Knighton910
Copy link

@nodejs/documentation - that should probably be cleared up.

I'm on it @bnoordhuis
I'll have it done in the following days, & I'll consult @chrisdickinson before it goes into queue for a PR

@filmerjarred
Copy link
Author

Yeah, I suspected that was the case re detached. Upon further testing I've found that the reason passing detached into the fork options wasn't working for me originally is that

childProcess.spawn("node", ["child.js"], {detached:true, stdio:[0, 1, 2, 'ipc']});
or
childProcess.fork("child.js", {detached:true})

doesn't work on windows (the child process just doesn't spawn), whereas

childProcess.spawn("node", ["child.js"], {detached:true, stdio:['pipe', 'pipe', 'pipe', 'ipc']});
or
childProcess.fork("child.js", {detached:true, silent:true});

works fine. My guess would be that spawning a child process with inherited fd's and the detached flags crashes it?

@bnoordhuis
Copy link
Member

I'm going to defer to @nodejs/platform-windows for that. The tests we have for that particular child_process+stdio pattern are disabled on Windows but I don't know the details.

@eljefedelrodeodeljefe
Copy link
Contributor

I am currently researching on this. The standard behaviour on unices is only to do setsid() but not ignoring SIGHUP. Meaning it terminates on closing the tty session. First, we could clear this up in docs, but anyhow we don't provide to possibility to opt-in for ignoring SIGHUP. That might be worth a PR to libuvor implementing it in js, given that the programmer is expecting orphaned processes. What would you think @bnoordhuis ?

I am researching this on windows, but isn't the child_process automatically detached by default on windows threading implementation?

At least there it's dispatching SIGHUP explicitly.

@bnoordhuis
Copy link
Member

we don't provide to possibility to opt-in for ignoring SIGHUP

You can install a handler for it like this:

process.on('SIGHUP', () => {});  // ignore

FWIW, I don't think it's a good idea to mix that with { detached: true } somehow. They're orthogonal concepts.

isn't the child_process automatically detached by default on windows threading implementation?

Depends on your definition of 'detached'. The Windows and POSIX process models are different enough that it's a bit of an apples vs. oranges comparison.

@eljefedelrodeodeljefe
Copy link
Contributor

My point would be to make it very explicit by providing some kind of child_process.release() or {relase: true} option, like what I believe go has:

process, err := os.StartProcess("/bin/sleep", []string{"/bib/sleep", "100"}, &attr)
if err == nil {

    // It is not clear from docs, but Realease actually detaches the process
    err = process.Release();
    if err != nil {
        fmt.Println(err.Error())
   }
} else {
    fmt.Println(err.Error())
}

Since there are a lot of SO questions and other discussions about this, that would ease it. Instead of using a state machine and a no-op.

Example taken from here

@eljefedelrodeodeljefe
Copy link
Contributor

@bnoordhuis tested the noop, and I believe it doesn't work:

This will close the child process anyhow (Mac OS X).

// child_detach_payload.js
const cp = require('child_process')
cp.fork("child_detach_payload.js", {detached:true})
// child_detach_payload.js
process.on('SIGHUP', () => {});  // ingore parents close event
setInterval(function() {
  console.log('-> detached program doing work here');
}, 1000)

@bnoordhuis
Copy link
Member

You mean when you close the terminal? I think that's because of OS X-specific behavior where writing to the tty fails with EIO. Also, it's possible the stock terminal emulator hard-kills any processes.

@eljefedelrodeodeljefe
Copy link
Contributor

Hmm. Interesting. Could reproduce on ubuntu though. I'll have a deeper look into the sources. Once I am through with osx and linux, I'll test on windows.

@jasnell
Copy link
Member

jasnell commented Jun 7, 2016

I believe this can be closed since #5330 landed. We can reopen this if that assumption is incorrect.

@jasnell jasnell closed this as completed Jun 7, 2016
misak113 added a commit to signageos/sdk that referenced this issue Mar 31, 2023
if the stdio is not set for child_process.fork, the windows fails without any error
it has to be 'ignore' or the option silent: true has to be set.
see nodejs/node#5146
see https://nodejs.org/api/child_process.html#child_processforkmodulepath-args-options
see https://nodejs.org/api/child_process.html#optionsdetached
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
child_process Issues and PRs related to the child_process subsystem. windows Issues and PRs related to the Windows platform.
Projects
None yet
Development

No branches or pull requests

6 participants