- 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.
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:
detail
possible cause
I found that error does not occur with this workaround code added.
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:
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:
So, in this case, EFALT error does not occur.