Ticket #4934 (new bug)
threadWaitRead works incorrectly on nonthreaded RTS
| Reported by: | slyfox | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | _|_ |
| Component: | Runtime System | Version: | 7.0.1 |
| Keywords: | Cc: | tibbe, bos | |
| Operating System: | Linux | Architecture: | x86_64 (amd64) |
| Type of failure: | Incorrect result at runtime | Difficulty: | |
| Test Case: | Blocked By: | ||
| Blocking: | Related Tickets: |
Description
I found out it in xmobar on ghc-7.0.1. When I ran it I got the following message:
xmobar: file descriptor 8954336 out of range for select (0--1024). Recompile with -threaded to work around this.
-threaded option works, but the message is absolutely misleading.
I've decided to track where so large descriptor could come, but there was no such place.
All xmobar does is:
do x11connection_fd <- connectionNumber d
threadWaitRead (Fd fd) -- here we die
x11connection_fd has value 3 at the time of call. This value comes from libX11 (via FFI, so I suspect it's a problem).
Another example (might be unrelated):
-- a.hs import Control.Concurrent -- 12 is picked at random as guaranteed to be invalid FD main = threadWaitRead 12 >> print "yet input!"
Building:
$ ghc --make -fforce-recomp a.hs -o a [1 of 1] Compiling Main ( a.hs, a.o ) Linking a ... $ ghc --make -fforce-recomp a.hs -threaded -o a.threaded [1 of 1] Compiling Main ( a.hs, a.o ) Linking a.threaded ...
Running:
$ ./a.threaded a.threaded: epollControl: invalid argument (Bad file descriptor)
Looks good.
And nonthreaded:
$ ./a "yet input!"
According to strace there was an error but it was not reported.
sf tmp # strace -etrace='select,write' ./a >/dev/null
select(13, [12], [], NULL, {134, 217727}) = -1 EBADF (Bad file descriptor) # this one
select(2, [], [1], NULL, {0, 0}) = 1 (out [1], left {0, 0})
write(1, "\"yet input!\"\n", 13) = 13
Side note: Haskeline seems to workaround this problem on it's own way.
libraries/haskeline/System/Console/Haskeline/Backend/Posix.hsc
-- Different versions of ghc work better using different functions. blockUntilInput :: Handle -> IO () #if __GLASGOW_HASKELL__ >= 611 -- threadWaitRead doesn't work with the new ghc IO library, -- because it keeps a buffer even when NoBuffering is set. blockUntilInput h = hWaitForInput h (-1) >> return () #else -- hWaitForInput doesn't work with -threaded on ghc < 6.10 -- (#2363 in ghc's trac) blockUntilInput h = unsafeHandleToFd h >>= threadWaitRead #endif

