-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
Child-Process: file-descriptor auto-closes when it shouldn't without triggering close events. #14046
Comments
Tested in latest LTS (6.11.1) and current (8.2.1) still have the problem. However my friend (runs Ubuntu, with node v8.2.1) does not have the same problem. |
can't reproduce with the latest. Can you increase the timeout (say 10 sec) to see if internal buffering is an issue? |
Using 10.0.0 I still get the same problem with that code, however then I up the interval to 10sec it works properly for quite a while. Then it just freezes... :\ I suspect that this may be some weird OS level obscurity, making it difficult to debug. Since the problem is still occurring I do not feel comfortable losing this issue, however, I wouldn't expect anyone to focus on it right now due to its niche. |
thanks for clarifying. I will see what happens underneath and let you know. |
In Linux everything works fine, the fd numbers seem to map correctly.
In Windows however, no data is transported exept the initial handshake. I don't know about a similar tracing mechanism in Windows so don't know what is happening inside. Somewhat simplified test case: $ cat 14046.js var spawn = require('child_process').spawn
var net = require('net')
if(process.argv[2] === 'child') {
var count = 0
var p1 = new net.Socket({ fd: 3, writeable: true, readable: true})
var p2 = new net.Socket({ fd: 4, writeable: true, readable: true})
p1.on('data', (d) => {
console.log(`p1 data: ${d.toString()}`)
})
p2.on('data', (d) => {
console.log(`p2 data: ${d.toString()}`)
})
setInterval(function () {
p1.write('p1')
p2.write('p2')
}, 10000)
} else {
var child = spawn(process.execPath, [process.argv[1], 'child'],
{stdio: ['pipe', 'inherit', 'inherit', 'pipe', 'pipe']}
)
child.stdio[3].on('data', (d) => {
console.log(`child data: ${d.toString()}`)
child.stdio[3].write('olleh')
})
child.stdio[4].on('data', (d) => {
console.log(`child data: ${d.toString()}`)
child.stdio[4].write('olleh')
})
child.stdio[3].write('start')
child.stdio[4].write('start')
} runs good on mac and linux, but data do not transfer in windows. I am just wondering whether the random selection of fd 3 and 4 were correct in the first place or not. How do we know what fd number is used internally? Doc does not seem to be very explicit in that regard. /cc @nodejs/child_process |
On Windows you don't; the test looks flawed to me. POSIX systems (Linux, macOS) open new fds at the lowest available slot but Windows is not POSIX and doesn't have such semantics. |
oh, yes! that fills all the gap, thanks! But then how, given the parent code, a child will handle this? there seem to be no way for identifying what descriptors the |
You can't right now but perhaps libuv could map the handles to CRT file descriptors in the child process. Completely untested but it would look something like this: diff --git a/deps/uv/src/win/process-stdio.c b/deps/uv/src/win/process-stdio.c
index 032e30935c..2a2afa19f3 100644
--- a/deps/uv/src/win/process-stdio.c
+++ b/deps/uv/src/win/process-stdio.c
@@ -470,9 +470,13 @@ void uv__stdio_noinherit(BYTE* buffer) {
count = CHILD_STDIO_COUNT(buffer);
for (i = 0; i < count; i++) {
HANDLE handle = CHILD_STDIO_HANDLE(buffer, i);
- if (handle != INVALID_HANDLE_VALUE) {
- SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
+ if (handle == INVALID_HANDLE_VALUE) {
+ continue;
+ }
+ if (i > 2) {
+ _open_osfhandle((intptr_t) handle, _O_RDWR);
}
+ SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
}
}
|
It's been 2yrs, I presume this is fixed, otherwise someone else would have ran into it and added something here - or created a new issue |
Because node's spawn() implementation is broken on windows Ref: nodejs/node#14046 https://github.com/mcollina/autocannon/pull/145/files
I have a master and a child process of which both repeatedly ping each other over fd: 3, and fd:4, however after 1 second the master stops receiving any messages from the child, and no close, end, finish, or error event is ever triggered.
Master:
Child:
Partial log:
The text was updated successfully, but these errors were encountered: