On Mon, May 5, 2014 at 10:04 PM, Alain O'Dea <alain.odea@gmail.com> wrote:
I'm trying to get to the bottom of a very tenacious bug in the GHC
Builder.

The details of how this happens are documented separately for reference:
https://gist.github.com/AlainODea/dc841046524cd7833da8

The Handles involved are returned by
System.Process.runInteractiveProcess.  They are non-blocking at the
Illumos kernel level.

It appears that maybeFillReadBuffer (called by hGetLine under the
hood) treats EAGAIN as an error:

http://hackage.haskell.org/package/base-4.7.0.0/docs/src/GHC-IO-Handle-Text.html#maybeFillReadBuffer

Is it expected that runInteractiveProcess would return non-blocking
Handles for stdout and stderr?

The non-blockingness should be hidden.

Your attempt to follow EAGAIN down the programmatic rabbit hole hasn't gotten you nearly far enough, I'm afraid. You stopped at a layer where the underlying non-blocking nature of the IO shouldn't be visible, so it would be inappropriate to check for EAGAIN there. As you'll notice if you follow the breadcrumbs further, it becomes quite difficult to spelunk through the various vtables to see what's really going on.

I think that you should be looking at GHC.IO.FD.readRawBufferPtr, as that's where the IO is ultimately happening. The trouble is, it calls throwErrnoIfMinus1RetryMayBlock, which should already be doing the right thing with EAGAIN. Sadly, I don't know what's going wrong here, but I'm sure you will need to go down a level or two of abstraction from where you are now before you'll find the source of the problem.