[GHC] #8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------------+------------------------------- Reporter: merijn | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: libraries/base | Version: 7.6.3 Keywords: patch | Operating System: Architecture: Unknown/Multiple | Unknown/Multiple Difficulty: Easy (less than 1 hour) | Type of failure: Runtime Blocked By: | crash Related Tickets: | Test Case: | Blocking: -------------------------------------------+------------------------------- Due to an unsafe coercion in GHC.Event.Poll.poll the implementation has a bug that on some platforms (.e.g. linux) results in subtly wrong semantics and on other platforms (e.g. OS X) downright crashes the runtime. The offending line is line 95 in GHC/Event/Poll.hsc: {{{ c_poll ptr (fromIntegral len) (fromIntegral (fromTimeout tout)) }}} `fromTimeout` returns a timeout in seconds as a value of type Int. `c_poll` takes a timeout in seconds as a value of type CInt. If the max value of Int is larger than that of CInt, this coercion results in an overflow, producing a negative value. The faulty semantics are in turn caused by passing this negative value as timeout to `c_poll`. This overflow happens on many 64bit platforms where GHC's Int is 64bit, but CInt is often 32bit. The result of passing a negative value to poll() depends on the platform, but is (on all platforms I checked) different from the desired semantics! On linux any negative timeouts are treated as infinite, this means that a poll() with a timeout that should be finite results in an infinitely blocking poll on linux! On OSX any negative timeout other than -1 (which is treated as infinity) is considered an invalid parameter, returning an error and crashing the runtime. A minimal example reproducing the error (on systems where `fromIntegral (maxBound :: Int) > (fromIntegral (maxBound :: CInt) :: Integer)`): {{{ import Control.Concurrent main = threadDelay maxBound }}} Using 64bit GHC on OSX this produces an immediate runtime crash. The attached patch solves the issue by comparing the Int timeout against the max value of CInt and, if necessary, looping multiple `c_poll` calls (with a timeout equal to `maxBound :: CInt`) if they return `0` (which indicates the timeout has expired with no events occurring). See also: https://github.com/merijn/packages- base/commit/6d8ea02a3f6a2cdb82a9ad786a8c4db780b92091 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------+------------------------------------------- Reporter: merijn | Owner: Type: bug | Status: patch Priority: normal | Milestone: Component: | Version: 7.6.3 libraries/base | Keywords: patch Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Easy (less than 1 hour) Unknown/Multiple | Blocked By: Type of failure: Runtime | Related Tickets: crash | Test Case: | Blocking: | -------------------------------+------------------------------------------- Changes (by igloo): * status: new => patch -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------+------------------------------------------- Reporter: merijn | Owner: Type: bug | Status: patch Priority: normal | Milestone: Component: | Version: 7.6.3 libraries/base | Keywords: patch Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Easy (less than 1 hour) Unknown/Multiple | Blocked By: Type of failure: Runtime | Related Tickets: crash | Test Case: | Blocking: | -------------------------------+------------------------------------------- Comment (by merijn): Previously patch is not sufficiently paranoid. It just moves the underflow from architectures where Int is smaller than CInt to architectures where CInt is smaller than Int. Because the `fromIntegral (maxBound :: CInt) :: Int` conversion underflows in the computation of `maxPollTimeout`. New patch deals with this by taking the max of `maxBound :: Int` and `fromIntegral (maxBound :: CInt) :: Int)`, as a result if the conversion from `maxBound :: CInt` to Int underflows the `maxPollTimeout` is turned into "maxBound :: Int", which is sufficient, as the poll function can't receive time outs bigger than that anyway. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------+------------------------------------------- Reporter: merijn | Owner: Type: bug | Status: patch Priority: normal | Milestone: Component: | Version: 7.6.3 libraries/base | Keywords: patch Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Easy (less than 1 hour) Unknown/Multiple | Blocked By: Type of failure: Runtime | Related Tickets: crash | Test Case: | Blocking: | -------------------------------+------------------------------------------- Comment (by merijn): Removed redundant fromIntegral from patch. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------+------------------------------------------- Reporter: merijn | Owner: Type: bug | Status: patch Priority: normal | Milestone: Component: | Version: 7.6.3 libraries/base | Keywords: patch Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Easy (less than 1 hour) Unknown/Multiple | Blocked By: Type of failure: Runtime | Related Tickets: crash | Test Case: | Blocking: | -------------------------------+------------------------------------------- Comment (by thoughtpolice): I currently can't reproduce this on amd64/Linux. I'll get my OS X machine out and try and merge it tomorrow. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------+------------------------------------------- Reporter: merijn | Owner: thoughtpolice Type: bug | Status: patch Priority: normal | Milestone: Component: | Version: 7.6.3 libraries/base | Keywords: patch Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Easy (less than 1 hour) Unknown/Multiple | Blocked By: Type of failure: Runtime | Related Tickets: crash | Test Case: | Blocking: | -------------------------------+------------------------------------------- Changes (by thoughtpolice): * owner: => thoughtpolice -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------+------------------------------------------- Reporter: merijn | Owner: thoughtpolice Type: bug | Status: patch Priority: normal | Milestone: Component: | Version: 7.6.3 libraries/base | Keywords: patch Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Easy (less than 1 hour) Unknown/Multiple | Blocked By: Type of failure: Runtime | Related Tickets: crash | Test Case: | Blocking: | -------------------------------+------------------------------------------- Comment (by merijn): Replying to [comment:4 thoughtpolice]:
I currently can't reproduce this on amd64/Linux. I'll get my OS X machine out and try and merge it tomorrow.
Right, the only effect on linux right now is that it will block indefinitely, rather than some finite time, which only matters if there's no wake-ups, which seems very unlikely to ever happen. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------+------------------------------------------- Reporter: merijn | Owner: thoughtpolice Type: bug | Status: closed Priority: normal | Milestone: Component: | Version: 7.6.3 libraries/base | Keywords: patch Resolution: fixed | Architecture: Unknown/Multiple Operating System: | Difficulty: Easy (less than 1 hour) Unknown/Multiple | Blocked By: Type of failure: Runtime | Related Tickets: crash | Test Case: | Blocking: | -------------------------------+------------------------------------------- Changes (by thoughtpolice): * status: patch => closed * resolution: => fixed Comment: I reproduced this on my OS X machine but didn't push it, it seems. The patches to base are pushed now; thanks Merijn, sorry for the delay. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------+------------------------------------- Reporter: merijn | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: | Version: 7.6.3 libraries/base | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Easy (less than 1 Unknown/Multiple | hour) Type of failure: Runtime | Blocked By: crash | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by merijn): * cc: hvr, ekmett (added) * keywords: patch => * status: closed => new * resolution: fixed => * owner: thoughtpolice => Comment: My "fixed" fix was still wrong, proper fix incoming on Phabricator -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion
-------------------------------------+-------------------------------------
Reporter: merijn | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: | Version: 7.6.3
libraries/base | Keywords:
Resolution: | Architecture: Unknown/Multiple
Operating System: | Difficulty: Easy (less than 1
Unknown/Multiple | hour)
Type of failure: Runtime | Blocked By:
crash | Related Tickets:
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
Comment (by Austin Seipp

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------+------------------------------------- Reporter: merijn | Owner: Type: bug | Status: merge Priority: normal | Milestone: 7.10.1 Component: | Version: 7.6.3 libraries/base | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Easy (less than 1 Unknown/Multiple | hour) Type of failure: Runtime | Blocked By: crash | Related Tickets: Test Case: | Blocking: | Differential Revisions: Phab:D407 | -------------------------------------+------------------------------------- Changes (by thoughtpolice): * status: new => merge * differential: => Phab:D407 * milestone: => 7.10.1 Comment: OK, closing *again*, for good this time hopefully. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------+------------------------------------- Reporter: merijn | Owner: Type: bug | Status: closed Priority: normal | Milestone: 7.10.1 Component: | Version: 7.6.3 libraries/base | Keywords: Resolution: fixed | Architecture: Unknown/Multiple Operating System: | Difficulty: Easy (less than 1 Unknown/Multiple | hour) Type of failure: Runtime | Blocked By: crash | Related Tickets: Test Case: | Blocking: | Differential Revisions: Phab:D407 | -------------------------------------+------------------------------------- Changes (by thoughtpolice): * status: merge => closed * resolution: => fixed -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------+------------------------------------- Reporter: merijn | Owner: Type: bug | Status: closed Priority: normal | Milestone: 7.10.1 Component: libraries/base | Version: 7.6.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Runtime crash | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D407 -------------------------------------+------------------------------------- Comment (by thomie): For posterity, other commits in this series: * 33ed16bd8b3d95dd18e401a3d64435d8675b5f86 {{{ Author: Merijn Verstraaten <> Date: Wed Jul 24 19:00:42 2013 +0100 *Really* RTS crash due to bad coercion. Previous commit only moved the coercion mistake to a different architecture (i.e. underflow could still occur on platforms where Int is smaller than CInt). This patch should definitively deal with all possible combinations. Signed-off-by: Austin Seipp <> }}} * 00e04e81fb127d716719a85d9387a98b664b7176 {{{ Author: Merijn Verstraaten <> Date: Wed Jul 24 14:37:25 2013 +0100 Fix OSX RTS crash due to bad coercion. The code coerces Int to CInt, which causes an overflow if Int is bigger than CInt (for example, Int 64bit, CInt 32 bit). This results in a negative value being passed to c_poll. On Linux all negative values are treated as infinite timeouts, which gives subtly wrong semantics, but is unlikely to produce actual bugs. OSX insists that only -1 is a valid value for infinite timeout, any other negative timeout is treated as an invalid argument. This patch replaces the c_poll call with a loop that handles the overflow gracefully by chaining multiple calls to poll to obtain the proper semantics. Signed-off-by: Austin Seipp <> }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:12 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion
-------------------------------------+-------------------------------------
Reporter: merijn | Owner:
Type: bug | Status: closed
Priority: normal | Milestone: 7.10.1
Component: libraries/base | Version: 7.6.3
Resolution: fixed | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: Runtime crash | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Revisions: Phab:D407
-------------------------------------+-------------------------------------
Comment (by Thomas Miedema

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------+------------------------------------- Reporter: merijn | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: 7.10.1 Component: libraries/base | Version: 7.6.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Runtime crash | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D407 Wiki Page: | -------------------------------------+------------------------------------- Changes (by alpmestan): * cc: alpmestan (added) Comment: The T8089 test case fails for those 3 ways: {{{ /tmp/ghctest-n4fi8zlk/test spaces/../../libraries/base/tests/T8089.run T8089 [bad exit code] (ghci) /tmp/ghctest-n4fi8zlk/test spaces/../../libraries/base/tests/T8089.run T8089 [bad exit code] (threaded1) /tmp/ghctest-n4fi8zlk/test spaces/../../libraries/base/tests/T8089.run T8089 [bad exit code] (threaded2) }}} I'll mark those tests as expected broken for those 3 ways for now, is the above a manifestation of an actual, "serious" problem? Or simply a timeout program quirk? Depending on the answer, I might create a new ticket (as the problem doesn't seem immediately related to this ticket). -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:14 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------+------------------------------------- Reporter: merijn | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: 7.10.1 Component: libraries/base | Version: 7.6.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Runtime crash | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D407 Wiki Page: | -------------------------------------+------------------------------------- Comment (by bgamari): What does the failed output look like? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:15 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------+------------------------------------- Reporter: merijn | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: 7.10.1 Component: libraries/base | Version: 7.6.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Runtime crash | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D407 Wiki Page: | -------------------------------------+------------------------------------- Comment (by alpmestan): Oops, forgot to include it in my previous comment. Here's what I get for say the 'ghci' way (same for threaded1 and threaded2 though): {{{ =====> T8089(ghci) 1 of 1 [0, 0, 0] cd "../../libraries/base/tests/T8089.run" && "/home/alp/ghc/inplace/test spaces/ghc-stage2" T8089.hs -dcore-lint -dcmm-lint -no-user-package-db -rtsopts -fno-warn-missed-specialisations -fshow-warning-groups -fdiagnostics-color=never -fno-diagnostics-show-caret -dno-debug-output --interactive -v0 -ignore-dot-ghci -fno-ghci-history +RTS -I0.1 -RTS < T8089.genscript Wrong exit code for T8089(ghci) (expected 99 , actual 0 ) *** unexpected failure for T8089(ghci) }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:16 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------+------------------------------------- Reporter: merijn | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: 7.10.1 Component: libraries/base | Version: 7.6.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Runtime crash | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D407 Wiki Page: | -------------------------------------+------------------------------------- Comment (by bgamari): Can you try running this test manually? I strongly suspect that the testsuite driver elides the relevant part of the output. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:17 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------+------------------------------------- Reporter: merijn | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: 7.10.1 Component: libraries/base | Version: 7.6.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Runtime crash | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D407 Wiki Page: | -------------------------------------+------------------------------------- Comment (by alpmestan): For the record, the test in question is: {{{#!hs -- can be found in libraries/base/tests/T8089.hs import Control.Concurrent main :: IO () main = threadDelay maxBound }}} Building it (I copied the CLI arguments from the threaded1 run): {{{ $ inplace/bin/ghc-stage2 -o T8089 libraries/base/tests/T8089.hs -dcore- lint -dcmm-lint -no-user-package-db -rtsopts -fno-warn-missed- specialisations -fshow-warning-groups -fdiagnostics-color=never -fno- diagnostics-show-caret -dno-debug-output -threaded -debug [1 of 1] Compiling Main ( libraries/base/tests/T8089.hs, libraries/base/tests/T8089.o ) Linking T8089 ... }}} Running it: {{{ $ ./T8089 $ echo $? 0 }}} (the expected return code is 99, we get 0) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:18 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------+------------------------------------- Reporter: merijn | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: 7.10.1 Component: libraries/base | Version: 7.6.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Runtime crash | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D407 Wiki Page: | -------------------------------------+------------------------------------- Comment (by alpmestan): Ben: any suggestion for what we should do with these failures? I'm still seeing them. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:19 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------+------------------------------------- Reporter: merijn | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: 7.10.1 Component: libraries/base | Version: 7.6.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Runtime crash | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D407 Wiki Page: | -------------------------------------+------------------------------------- Comment (by bgamari): Hmm, let's open a new ticket so we can investigate. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:20 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------+------------------------------------- Reporter: merijn | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: 7.10.1 Component: libraries/base | Version: 7.6.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Runtime crash | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D407 Wiki Page: | -------------------------------------+------------------------------------- Comment (by merijn): FWIW, the original test was...rather hacky to begin with. It was basically relying on the test-suite terminating the job after X seconds and producing a timeout, since the original bug caused that program to immediately crash. So prime suspects would be any change in the timeout mechanism of the testsuite producing a different error code. Also, if T8089 terminates when you run it on the commandline something is *obviously* wrong as that program shouldn't exit until, approximately 292,471 years after starting. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:21 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8089: Implementation of GHC.Event.Poll.poll is broken due to bad coercion -------------------------------------+------------------------------------- Reporter: merijn | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: 7.10.1 Component: libraries/base | Version: 7.6.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Runtime crash | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D407 Wiki Page: | -------------------------------------+------------------------------------- Comment (by alpmestan): These failures will be discussed in #15158. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8089#comment:22 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC