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

EFAULT error in process.stdout.write(data, 'hex') #8251

Closed
kotarondo opened this issue Aug 24, 2016 · 3 comments
Closed

EFAULT error in process.stdout.write(data, 'hex') #8251

kotarondo opened this issue Aug 24, 2016 · 3 comments
Assignees
Labels
confirmed-bug Issues with confirmed bugs. net Issues and PRs related to the net subsystem.

Comments

@kotarondo
Copy link

  • Version:6.4.0 (or lower versions)
  • Platform: macosx (or any other unix/linux)
  • Subsystem: none

summary

This test program stops with EFAULT error
when it is executed with piped stdout.

EFAULT error must not occur in writing to stdout.
It seems a bug in Node.js.

test.js:

var data = new Buffer(1000000).toString('hex');

function write_loop() {
    while (process.stdout.write(data, 'hex'));
}

process.stdout.on('drain', write_loop);

write_loop();

function memory_pressure() {
    var val = [];
    for (var i = 0; i < 1000000; i++) {
        val[i] = i;
    }
    return val;
}

setInterval(memory_pressure, 100);

detail

% node test.js | cat >/dev/null

events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: write EFAULT
    at exports._errnoException (util.js:1026:11)
    at WriteWrap.afterWrite (net.js:794:14)
  • The stdout of 'node test.js' must be piped in order to result EFAULT error.
  • 'hex' encoding is also needed.
  • EFAULT error seldom occurs without memory_pressure.

possible cause

I found that error does not occur with this workaround code added.

var orig_writeBuffer = process.stdout._handle.writeBuffer;
process.stdout._handle.writeBuffer = function(req, b) {
    req.keepReferenceForWorkaround = b;
    orig_writeBuffer.call(this, req, b);
}

process.stdout._handle.writeBuffer actually is native-code
and it seems it assumes a reference of passed buffer is kept alive until write-completion.

In case of 'hex' encoding, passed buffer was created in
createWriteReq() in node/lib/net.js as follows:

default:
      return handle.writeBuffer(req, Buffer.from(data, encoding));

So, this buffer can be garbage-collected if handler.writeBuffer does not keep the reference alive.

other information

handle.writeBuffer is used also in case of 'buffer' encoding,
but the passed buffer is stored in the request object
in Socket.prototype._writeGeneric() (node/lib/net.js) as follows:

   if (data instanceof Buffer) {
      req.buffer = data;  // Keep reference alive.
      enc = 'buffer';
    } else {
      enc = encoding;
    }
    err = createWriteReq(req, this._handle, data, enc);

So, in this case, EFALT error does not occur.

@addaleax addaleax added the confirmed-bug Issues with confirmed bugs. label Aug 24, 2016
@addaleax
Copy link
Member

Thanks for the bug report! I can confirm the bug and will take a look.

@addaleax addaleax self-assigned this Aug 24, 2016
@addaleax addaleax added the net Issues and PRs related to the net subsystem. label Aug 24, 2016
addaleax added a commit to addaleax/node that referenced this issue Aug 24, 2016
Set the `req.buffer` property, which serves as a way of keeping
a `Buffer` alive that is being written to a stream, on the C++
side instead of the JS side.

This closes a hole where buffers that were temporarily created
in order to write strings with uncommon encodings (e.g. `hex`)
were passed to the native side without being set as `req.buffer`.

Fixes: nodejs#8251
@addaleax
Copy link
Member

I’ve created a proposed fix at #8252@kotarondo thanks for the detailed bug report, again. Would you mind taking a look over there?

@kotarondo
Copy link
Author

I have checked the fix, and I didn't find any problem in there.

addaleax added a commit to addaleax/node that referenced this issue Aug 27, 2016
Set the `req.buffer` property, which serves as a way of keeping
a `Buffer` alive that is being written to a stream, on the C++
side instead of the JS side.

This closes a hole where buffers that were temporarily created
in order to write strings with uncommon encodings (e.g. `hex`)
were passed to the native side without being set as `req.buffer`.

Fixes: nodejs#8251
PR-URL: nodejs#8252
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
MylesBorins pushed a commit that referenced this issue Sep 4, 2016
Set the `req.buffer` property, which serves as a way of keeping
a `Buffer` alive that is being written to a stream, on the C++
side instead of the JS side.

This closes a hole where buffers that were temporarily created
in order to write strings with uncommon encodings (e.g. `hex`)
were passed to the native side without being set as `req.buffer`.

Fixes: #8251
PR-URL: #8252
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Fishrock123 pushed a commit to Fishrock123/node that referenced this issue Sep 8, 2016
Set the `req.buffer` property, which serves as a way of keeping
a `Buffer` alive that is being written to a stream, on the C++
side instead of the JS side.

This closes a hole where buffers that were temporarily created
in order to write strings with uncommon encodings (e.g. `hex`)
were passed to the native side without being set as `req.buffer`.

Fixes: nodejs#8251
PR-URL: nodejs#8252
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Fishrock123 pushed a commit that referenced this issue Sep 9, 2016
Set the `req.buffer` property, which serves as a way of keeping
a `Buffer` alive that is being written to a stream, on the C++
side instead of the JS side.

This closes a hole where buffers that were temporarily created
in order to write strings with uncommon encodings (e.g. `hex`)
were passed to the native side without being set as `req.buffer`.

Fixes: #8251
PR-URL: #8252
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
MylesBorins pushed a commit that referenced this issue Sep 28, 2016
Set the `req.buffer` property, which serves as a way of keeping
a `Buffer` alive that is being written to a stream, on the C++
side instead of the JS side.

This closes a hole where buffers that were temporarily created
in order to write strings with uncommon encodings (e.g. `hex`)
were passed to the native side without being set as `req.buffer`.

Fixes: #8251
PR-URL: #8252
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
rvagg pushed a commit that referenced this issue Oct 18, 2016
Set the `req.buffer` property, which serves as a way of keeping
a `Buffer` alive that is being written to a stream, on the C++
side instead of the JS side.

This closes a hole where buffers that were temporarily created
in order to write strings with uncommon encodings (e.g. `hex`)
were passed to the native side without being set as `req.buffer`.

Fixes: #8251
PR-URL: #8252
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
MylesBorins pushed a commit that referenced this issue Oct 26, 2016
Set the `req.buffer` property, which serves as a way of keeping
a `Buffer` alive that is being written to a stream, on the C++
side instead of the JS side.

This closes a hole where buffers that were temporarily created
in order to write strings with uncommon encodings (e.g. `hex`)
were passed to the native side without being set as `req.buffer`.

Fixes: #8251
PR-URL: #8252
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug Issues with confirmed bugs. net Issues and PRs related to the net subsystem.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants