Skip to content

threadWaitRead works incorrectly on nonthreaded RTS

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
Trac metadata
Trac field Value
Version 7.0.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Runtime System
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system Unknown/Multiple
Architecture Unknown/Multiple
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information