[GHC] #12750: hGetContents leads to late/silent failures

GHC ghc-devs at haskell.org
Sat Jan 21 09:42:25 UTC 2017


#12750: hGetContents leads to late/silent failures
-------------------------------------+-------------------------------------
        Reporter:  massimo.zaniboni  |                Owner:
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Core Libraries    |              Version:  8.0.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  Incorrect result  |            Test Case:
  at runtime                         |  https://github.com/massimo-
                                     |  zaniboni/ghc_lazy_file_content_error
      Blocked By:                    |             Blocking:
 Related Tickets:  #9236             |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by massimo.zaniboni):

 Replying to [comment:2 rwbarton]:

 > Indeed, mixing `hGetContents` and `bracket` isn't recommended.

 I like lazy functions like `Data.Text.Lazy.hGetContents` because I can
 process file content chunk by chunk using a constant amount of RAM, and
 the code is very elegant.

 In any case the problem is related to any type of lazy evaluation using a
 resource managed by `bracket`, so not only `hGetContents`.

 More clearly there are two bugs:

 1) when the code reads the content of a closed file handle, instead of
 returning a run-time exception, a normal EOF is returned, and the
 application code has a bad behavior, because normal code path is executed
 instead of processing the exception.

 2) `bracket` does not work well with resources processed in a lazy way,
 because the thunk using the resource can be used after `bracket` has
 closed it, generating unexpected run-time errors. So the best semantic of
 `bracket` should be a strict evaluation of the result. It is a behavior
 more predictable and similar to Resource Acquisition Is Initialization
 (RAII) semantic of C++. But probably this is not the best place for
 signaling this.

 By the way I solved the problem executing with strict semantic all the
 file processing instructions inside `bracket`. File content is still
 processed chunk by chunk, but the handle is closed only at the end, when
 the result is returned.

 So my work-around rule is: use `bracket` only with strict semantic.

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


More information about the ghc-tickets mailing list