Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Unexpected child_process + stdout behavior change from 0.6.5 to 0.6.6 #2507

Closed
Hainish opened this issue Jan 11, 2012 · 7 comments
Closed

Unexpected child_process + stdout behavior change from 0.6.5 to 0.6.6 #2507

Hainish opened this issue Jan 11, 2012 · 7 comments

Comments

@Hainish
Copy link

Hainish commented Jan 11, 2012

When starting a child process with spawn, a self-exit from the parent process and a subsequent write to stdout from the child causes the child to crash unexpectedly. Bug emerged in 0.6.6, Linux x64.

Observed when running process.js:

process.js

var spawn = require("child_process").spawn;

var child = spawn("node", ['child.js']);
child.stdout.on('data', function(data){
  if(data.toString().indexOf("Child started") != -1){
    console.log("Child process started");
    process.exit();
  }
});

child.js

console.log('Child started');

var spawn = require("child_process").spawn;

var grandchild = spawn('node', ['grandchild.js']);
grandchild.stdout.on('data', function(data){
  process.stdout.write('I ' + data);
});

grandchild.js

var x =0;
setInterval(function(){
  console.log(x);
  x++;
}, 1000);
@bnoordhuis
Copy link
Member

13324bf seems to be the commit that breaks your test case. Will investigate.

@piscisaureus
Copy link

On Windows I get the following message. Is that the same as you guys?

node.js:284
        throw new Error('process.stdout cannot be closed');
              ^
Error: process.stdout cannot be closed
    at Socket.<anonymous> (node.js:284:15)
    at Object.afterWrite [as oncomplete] (net.js:478:10)

The code using to test:

var spawn = require('child_process').spawn;
spawn('node', ['-e', 'setTimeout(function(){console.log("fooo");}, 2000)'], {customFds:[-1,-1,2]});
process.exit(0);

@bnoordhuis
Copy link
Member

On Windows I get the following message. Is that the same as you guys?

Yes. The error is thrown by the child process.

@piscisaureus
Copy link

Apparently the fd that the child process uses becomes invalid because the master dies (this is expected).

After a stdout write fails, net.js tries to close it with an error status. However closing stdout is now forbidden and makes the program crash.

@isaacs
Copy link

isaacs commented Jan 12, 2012

Can we just have that error not crash the program? Ie, instead of throwing, just do nothing?

@bnoordhuis
Copy link
Member

That's what it was doing before 13324bf so the question is why that behaviour was changed. @igorzi?

@igorzi
Copy link

igorzi commented Jan 14, 2012

I believe this was done to make it explicit that closing stdout/stderr shouldn't be done (if it's just a noop then people would wrongfully assume that underlying handle actually got closed). Perhaps net.js should try looking at this._isStdio, and not try to close it if it's stdio handle?

isaacs added a commit to isaacs/node-v0.x-archive that referenced this issue Jan 27, 2012
…treams

Also, if an error is already provided, then raise the provided
error, rather than throwing it with a less helpful 'stdout cannot
be closed' message.

This is important for properly handling EPIPEs.
@isaacs isaacs closed this as completed in ff0f0ae Jan 27, 2012
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants