Ticket #724 (closed bug: fixed)

Opened 6 years ago

Last modified 2 years ago

tee complains if used in a process started by ghc

Reported by: guest Owned by:
Priority: high Milestone: 6.8.1
Component: libraries/base Version: 6.4.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Difficulty: Moderate (less than a day)
Test Case: concio001 Blocked By:
Blocking: Related Tickets:

Description

I have the following program:

import System

main = getArgs >>= system . head

i.e., a simple wrapper around the system command. I compile this using

ghc -o Sys --make Sys.hs

into a binary Sys. If I then call

./Sys "yes | head -n 20000000 | tee /dev/null"

the program quits with the message tee: write error. I tried on some machines, and on some I have to increase the argument to head, but at some point it always fails. Calling the shell command directly gives no error. However, calling

./Sys "yes | head -n 20000000" | tee /dev/null

(note the difference!) also fails.

This bug is a showstopper for my current project. In my program, I call other programs which internally employ tee for logging. Whenever there is a lot of screen output, there seems to be a good chance that my program fails.

I have no idea if this is a problem with tee or with ghc, but I couldn't yet reproduce it in any non-ghc context.

Andres Loeh

Attachments

nonblock.patch Download (51.2 KB) - added by simonmar 5 years ago.

Change History

Changed 6 years ago by simonmar

  • difficulty changed from Unknown to Moderate (1 day)
  • component changed from Compiler to libraries/base
  • milestone set to 6.6

We know why this is: it's because GHC puts stdin/stdout into non-blocking mode, and tee doesn't like it.

There's a fix for the threaded RTS. We could avoid putting the standard file descriptors into non-blocking mode, and instead make blocking FFI calls to access them. This can't be used in the non-threaded RTS. (GHC is now linked with the threaded RTS, so this would fix the case in this bug report).

It's not a simple fix, so I'll probably punt until 6.6.

Changed 6 years ago by guest

This bug is quite a showstopper for Andres application. Any run with much text output and it's almost guarantied that it will fail.

I belive that this issue is related to another issue as well: Locking/unlocking screen output in a terminal with Ctrl+S / Ctrl+Q doesn't work. Once a terminal output is locked it can't be unlocked and the result is that the application fails with tee: write error.

Lennart Kolmodin

Changed 5 years ago by igloo

  • milestone changed from 6.6 to 6.8

Changed 5 years ago by guest

I'd also like to ping this bug. It also affects arbitrary Gentoo users. Gentoo's portage can be configured to produce build logs for all the packages. This is a global switch. When enabled, all building is filtered through "tee". If any of the ghc compiler calls produces lots of output, there is a risk that compilation fails. In the past, I "fixed" this by making ghc produce less output (by removing warning flags, for instance), but in general, the only solution that works is to tell people to disable logging, which is annoying.

For reference:

 http://bugs.gentoo.org/show_bug.cgi?id=111183

Andres Loeh

Changed 5 years ago by igloo

  • priority changed from normal to high

Changed 5 years ago by simonmar

Changed 5 years ago by simonmar

Patch to package/base that attempts to address this attached. It's not a perfect solution, so I'm going to let it simmer for a while. If you're interested in this bug, please try the patch if you can.

Changed 5 years ago by simonmar

  • milestone changed from 6.8 to 6.6.2

Changed 5 years ago by simonmar

  • status changed from new to closed
  • testcase set to concio001
  • resolution set to fixed

Fixed, more or less.

Mon May  7 05:35:37 PDT 2007  Simon Marlow <simonmar@microsoft.com>
  * FIX: #724 (tee complains if used in a process started by ghc)
  
  Now, we only set O_NONBLOCK on file descriptors that we create
  ourselves.  File descriptors that we inherit (stdin, stdout, stderr)
  are kept in blocking mode.  The way we deal with this differs between
  the threaded and non-threaded runtimes:
  
   - with -threaded, we just make a safe foreign call to read(), which
     may block, but this is ok.
  
   - without -threaded, we test the descriptor with select() before
     attempting any I/O.  This isn't completely safe - someone else
     might read the data between the select() and the read() - but it's
     a reasonable compromise and doesn't seem to measurably affect
     performance.

test cases to follow.

Changed 4 years ago by simonmar

  • milestone changed from 6.6.2 to 6.8.1

Changed 3 years ago by simonmar

  • architecture changed from Unknown to Unknown/Multiple

Changed 3 years ago by simonmar

  • os changed from Unknown to Unknown/Multiple

Changed 2 years ago by simonmar

  • difficulty changed from Moderate (1 day) to Moderate (less than a day)
Note: See TracTickets for help on using tickets.