Repository navigation
Issue passing file descriptors in OS X #7512
Copy link
Copy link
Closed
Labels
child_processIssues and PRs related to the child_process subsystem.Issues and PRs related to the child_process subsystem.macosIssues and PRs related to the macOS platform.Issues and PRs related to the macOS platform.netIssues and PRs related to the net subsystem.Issues and PRs related to the net subsystem.
Description
- Version:
v7.0.0-pre - Platform:
OS X 10.11.5 - Subsystem: child_process
The test-cluster-net-send.js test is sometimes failing when running the test suite in my OS X with the following output:
=== release test-cluster-net-send ===
Path: parallel/test-cluster-net-send
[32787] master
[32789] worker
assert.js:90
throw new assert.AssertionError({
^
AssertionError: false == true
at process.<anonymous> (/Users/sgimeno/node/node/test/parallel/test-cluster-net-send.js:29:12)
at process.g (events.js:286:16)
at emitOne (events.js:101:20)
at process.emit (events.js:188:7)
Command: out/Release/node /Users/sgimeno/node/node/test/parallel/test-cluster-net-send.js
After investigating the issue it looks like that the error happens only when the fd that passes the worker to the master is closed before it is received in the master process. The following patch, that closes the fd only after receiving the NODE_HANDLE_ACK message fixes the issue for me.
diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js
index 789c29e..44a245e 100644
--- a/lib/internal/child_process.js
+++ b/lib/internal/child_process.js
@@ -96,8 +96,8 @@ const handleConversion = {
postSend: function(handle, options) {
// Close the Socket handle after sending it
- if (handle && !options.keepOpen)
- handle.close();
+ //if (handle && !options.keepOpen)
+ // global_handle = handle;
},
got: function(message, handle, emit) {
@@ -465,6 +465,11 @@ function setupChannel(target, channel) {
target.on('internalMessage', function(message, handle) {
// Once acknowledged - continue sending handles.
if (message.cmd === 'NODE_HANDLE_ACK') {
+ if (target._pending_handle) {
+ target._pending_handle.close();
+ target._pending_handle = null;
+ }
+
assert(Array.isArray(target._handleQueue));
var queue = target._handleQueue;
target._handleQueue = null;
@@ -615,8 +620,13 @@ function setupChannel(target, channel) {
req.oncomplete = function() {
if (this.async === true)
control.unref();
- if (obj && obj.postSend)
+ if (obj && obj.postSend) {
obj.postSend(handle, options);
+ if (handle && !options.keepOpen) {
+ assert(!target._pending_handle);
+ target._pending_handle = handle;
+ }
+ }This seems strange to me as my understanding was that closing the file descriptor after sending it was safe (at least in my Linux box I have not been able to reproduce the same issue). Thoughts?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
child_processIssues and PRs related to the child_process subsystem.Issues and PRs related to the child_process subsystem.macosIssues and PRs related to the macOS platform.Issues and PRs related to the macOS platform.netIssues and PRs related to the net subsystem.Issues and PRs related to the net subsystem.
Activity
bnoordhuis commentedon Jul 2, 2016
Someone reported the same issue on the libuv mailing list recently: https://groups.google.com/d/msg/libuv/CuWJ28ZMmpY/YlIIeKdPBAAJ
I haven't been able to reproduce with OS X 10.8.5 or on other operating systems. It's possible it's a regression in newer xnu kernels, maybe a failure to increment the file description's reference count in SCM_RIGHTS operations.
I don't think we can work around that in libuv (it doesn't know when the file descriptor has been received) so a node.js workaround might be the best course of action.
santigimeno commentedon Jul 2, 2016
@bnoordhuis Thanks for the info. I'll follow with a PR later today. Is there a place to report this upstream?
bnoordhuis commentedon Jul 2, 2016
You mean to Apple? They have something called Radar but it's a massive black hole, don't expect any feedback.
child_process: workaround fd passing issue on OS X
child_process: workaround fd passing issue on OS X
child_process: workaround fd passing issue on OS X
child_process: workaround fd passing issue on OS X