[commit: packages/base] master: *Really* RTS crash due to bad coercion. (9c0eb7b)

git at git.haskell.org git at git.haskell.org
Thu Nov 7 13:57:12 UTC 2013


Repository : ssh://git@git.haskell.org/base

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/9c0eb7b8d7978f0abc98296dcab050f4b6249c61/base

>---------------------------------------------------------------

commit 9c0eb7b8d7978f0abc98296dcab050f4b6249c61
Author: Merijn Verstraaten <merijn at inconsistent.nl>
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 <aseipp at pobox.com>


>---------------------------------------------------------------

9c0eb7b8d7978f0abc98296dcab050f4b6249c61
 GHC/Event/Poll.hsc |   18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/GHC/Event/Poll.hsc b/GHC/Event/Poll.hsc
index 6d089fb..572cff6 100644
--- a/GHC/Event/Poll.hsc
+++ b/GHC/Event/Poll.hsc
@@ -121,9 +121,23 @@ poll p mtout f = do
                then c_pollLoop ptr len (fromIntegral (tout - maxPollTimeout))
                else return result
 
-    -- Timeout of c_poll is limited by max value of CInt
+    -- We need to account for 3 cases:
+    --     1. Int and CInt are of equal size.
+    --     2. Int is larger than CInt
+    --     3. Int is smaller than CInt
+    --
+    -- In case 1, the value of maxPollTimeout will be the maxBound of Int.
+    --
+    -- In case 2, the value of maxPollTimeout will be the maxBound of CInt,
+    -- which is the largest value accepted by c_poll. This will result in
+    -- c_pollLoop recursing if the provided timeout is larger.
+    --
+    -- In case 3, "fromIntegral (maxBound :: CInt) :: Int" wil result in a
+    -- negative Int, max will thus return maxBound :: Int. Since poll doesn't
+    -- accept values bigger than maxBound :: Int and CInt is larger than Int,
+    -- there is no problem converting Int to CInt for the c_poll call.
     maxPollTimeout :: Int
-    maxPollTimeout = fromIntegral (maxBound :: CInt)
+    maxPollTimeout = max maxBound (fromIntegral (maxBound :: CInt))
 
 fromTimeout :: E.Timeout -> Int
 fromTimeout E.Forever     = -1



More information about the ghc-commits mailing list