Skip to content

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

Description

@kotarondo
  • 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:

vardata=newBuffer(1000000).toString('hex');functionwrite_loop(){while(process.stdout.write(data,'hex'));}process.stdout.on('drain',write_loop);write_loop();functionmemory_pressure(){varval=[];for(vari=0;i<1000000;i++){val[i]=i;}returnval;}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.

varorig_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:
returnhandle.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(datainstanceofBuffer){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.

Metadata

Metadata

Assignees

Labels

confirmed-bugIssues with confirmed bugs.netIssues and PRs related to the net subsystem.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions