[GHC] #8213: Bad error message when using lazy IO to read from closed handle

GHC ghc-devs at haskell.org
Thu Nov 20 16:45:28 UTC 2014


#8213: Bad error message when using lazy IO to read from closed handle
-------------------------------------+-------------------------------------
              Reporter:  nh2         |            Owner:
                  Type:  bug         |           Status:  infoneeded
              Priority:  normal      |        Milestone:
             Component:  Core        |          Version:  7.6.3
  Libraries                          |         Keywords:
            Resolution:              |     Architecture:  Unknown/Multiple
      Operating System:              |       Difficulty:  Unknown
  Unknown/Multiple                   |       Blocked By:
       Type of failure:  Incorrect   |  Related Tickets:
  result at runtime                  |
             Test Case:              |
              Blocking:              |
Differential Revisions:              |
-------------------------------------+-------------------------------------
Changes (by thomie):

 * cc: core-libraries-committee@… (added)
 * failure:  Documentation bug => Incorrect result at runtime
 * status:  new => infoneeded
 * component:  Runtime System => Core Libraries


Old description:

> Today I accidentally wrote this code:
>
> {{{
> filesEqual :: FilePath -> FilePath -> IO Bool
> filesEqual f1 f2 = do
>   equal <- withBinaryFile f1 ReadMode $ \f1 ->
>     withBinaryFile f2 ReadMode $ \f2 ->
>       c1 <- BSL.hGetContents h1
>       c2 <- BSL.hGetContents h2
>       return (c1 == c2)
>   return $! equal
> }}}
>
> The problem is that I should have done the forcing before the files are
> closed:
>
> {{{
> return $! (c1 == c2)
> }}}
>
> I got the incredibly unhelpful error message
>
> {{{
> myprogram: myfile.txt: illegal operation
> }}}
>
> It took me 2 hours and strace to find out what was going on, especially
> because around every file open() there are multiple things that map top
> IllegalOperation (e.g. the ENOTTY from the ioctl that checks whether the
> device is a TTY).
>
> Can we give a better error message here, at least mentioning that the
> problem has to do with closed (and GC'd) handles?

New description:

 Today I accidentally wrote this code:

 {{{
 import System.IO
 import Data.ByteString.Lazy as BSL

 filesEqual :: FilePath -> FilePath -> IO Bool
 filesEqual f1 f2 = do
   equal <- withBinaryFile f1 ReadMode $ \h1 ->
     withBinaryFile f2 ReadMode $ \h2 -> do
       c1 <- BSL.hGetContents h1
       c2 <- BSL.hGetContents h2
       return (c1 == c2)
   return $! equal

 main = filesEqual "test.hs" "test.hs" >>= print
 }}}

 The problem is that I should have done the forcing before the files are
 closed:

 {{{
 return $! (c1 == c2)
 }}}

 I got the incredibly unhelpful error message

 {{{
 test: test.hs: illegal operation
 }}}

 It took me 2 hours and strace to find out what was going on, especially
 because around every file open() there are multiple things that map top
 IllegalOperation (e.g. the ENOTTY from the ioctl that checks whether the
 device is a TTY).

 Can we give a better error message here, at least mentioning that the
 problem has to do with closed (and GC'd) handles?

--

Comment:

 I can not reproduce the problem. nh2: which OS were you using? Can you try
 again?

 On Linux, I get the following (nice) error message:
 {{{
 $ ghc-7.6.3 test.hs
 ...
 $ ./test
 test: test.hs: hGetBufSome: illegal operation (handle is closed)
 }}}

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8213#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list