[squeak-dev] Fwd: CommandShell outputAndError Bug Report

David T. Lewis lewis at mail.msen.com
Thu Jan 25 00:46:20 UTC 2018


On Wed, Jan 24, 2018 at 06:31:40AM -0700, Sean P. DeNigris wrote:
> This was on Pharo's #offtopic Discord channel, where I assume David Lewis
> would not see it???
> 
> > lukego - Yesterday at 8:49 AM
> > I'm not sure how to report a bug on CommandShell so I will just write this
> > here so that it is 
> > somewhere:
> > PipeJunction>>outputAndError is broken because it attempts to first
> > completely read stdout 
> > and then to completely read stderr. These streams should actually be read
> > in parallel. 
> > Otherwise you have a deadlock when a subprocess fills up its stderr
> > because it will become 
> > blocked on a write(2,...) system call hoping for Pharo to drain the buffer
> > and make space on 
> > stderr but that never happens because Pharo is only polling stdout.
> > I'm working around this with 2>&1 i.e. making sure that only stdout is
> > used and never stderr.
> 
> I don't think the OP is subscribed to this list, but I'm happy to pass
> responses back and forth.


Hi Sean,

Thanks for forwarding this, I appreciate it.

lukego is very likely right. This and many other example methods and convenience
methods in OSProcess/CommandShell can lead to conditions that block processes,
and in some cases (e.g reading from a blocking stream that has not data) can
block the VM.

In general it is necessary to ensure that input streams are set to be non-blocking,
and it can be helpful to read input in an asynchronous manner, with AIO events
triggering reads into buffers. Class BufferedAsyncFileReadStream does this
for example, and ProxyPipeline (which represents the evaluation of a command
pipeline in CommandShell) takes care of much of the housekeeping.

That said, #outputAndError does provide a convenient way to get the stdout and
stderr output for simple cases such as these:

  (PipeableOSProcess command: '/bin/echo this is a test') outputAndError
    ==> #('this is a test ' '')

  (PipeableOSProcess command: '/bin/FOO this is a test') outputAndError
    ==> #('' '/bin/sh: 1: /bin/FOO: not found ')

This would not be a reliable way to get the output from a program that generates
a lot of output, but for simple demonstration purposes like the above it
can be helpful.

Dave



More information about the Squeak-dev mailing list