Opened 14 months ago

Closed 13 months ago

Last modified 13 months ago

#12757 closed bug (fixed)

Compiled program segfaults at -O1

Reported by: hvr Owned by:
Priority: highest Milestone: 8.0.2
Component: Compiler Version: 8.1
Keywords: Cc: ezyang
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Runtime crash Test Case:
Blocked By: Blocking:
Related Tickets: #11312, #12585, #12855 Differential Rev(s):
Wiki Page:

Description

This affects GHC 8.0.2dev (d84a824cebe94711528727bcb587bfc369ec36a2) as well as GHC HEAD (c23dc6164d54eacc654516b885104dc8b7678f16)

The following program results in a segfault when compiled at -O1 or more:

{-# LANGUAGE OverloadedStrings #-}

module Main (main) where

import           Data.ByteString        (ByteString)
import qualified Data.ByteString        as B

answers :: [ByteString]
answers = map (B.filter (/= 0x20))
    [ "e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855"
    , "d7a8fbb3 07d78094 69ca9abc b0082e4f 8d5651e4 6d3cdb76 2d02d0bf 37c9e592"
    , "e4c4d8f3 bf76b692 de791a17 3e053211 50f7a345 b46484fe 427f6acc 7ecc81be"
    , "ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad"
    , "248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1"
    , "cf5b16a7 78af8380 036ce59e 7b049237 0b249b11 e8f07a51 afac4503 7afee9d1"
    , "cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0"
    ]

x, y :: ByteString
x = "e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855"
y = B.filter (/= 0x20) x

main :: IO ()
main = do
    print (seq x ())
    print (seq y ())
    print (length answers)
    print (seq (head answers) ()) -- segfault!
$ ghc-8.0.2 -fforce-recomp --make -O1 bug.hs && ./bug 
[1 of 1] Compiling Main             ( bug.hs, bug.o )
Linking bug ...
()
()
7
Segmentation fault
$ ghc-8.0.2 -fforce-recomp --make -O0 bug.hs && ./bug 
[1 of 1] Compiling Main             ( bug.hs, bug.o )
Linking bug ...
()
()
7
()

I haven't yet investigated why this happens.

Change History (10)

comment:1 Changed 14 months ago by hvr

I was informed by slyfox that this is much related (almost to the point of being a duplicate) of #12585, which in turn is a duplicate of #11312

I do consider this regression (relative to GHC 8.0.1) a blocker for GHC 8.0.2 as the repro-case above is code that's surely not exotic...

Last edited 14 months ago by hvr (previous) (diff)

comment:2 Changed 14 months ago by simonpj

Wait... how could inlining or not make a seg-fault? The above discussion shows that it can affect a boolean value, but not seg-fault!

comment:3 Changed 14 months ago by bgamari

I've done a bisection of this on ghc-8.0; according to the bisection the culprit is 2a9767ed596679ddf21b7edfa9fc6410443c2a01. I have yet to verify that reverting on ghc-8.0 HEAD fixes the issue. I'm currently waiting for a build to confirm this.

comment:4 Changed 14 months ago by bgamari

Cc: ezyang added

comment:5 Changed 14 months ago by bgamari

comment:6 Changed 14 months ago by bgamari

Siarheit had some insight on this. The problem here is essentially that bytestring traverses a ByteString by walking until currPtr == ( "literal"# +# length "literal"# ) where currPtr is initialized with "literal"#. This means that if "literal"# is inlined twice, you will end up with currPtr and "literal"# +# length "literal"# pointing into two separate chunks of memory, with who-knows-what in between.

comment:7 Changed 14 months ago by simonpj

Ah! Good insight. comment:3 of #11312 would nail this problem, and we should do that anyway.

Short term, not duplicating literal strings seems like the way forward.

They are duplicated in CorePrep, apparently because of

  • Edwards's patch for #12076 made CorePrep a bit more gung ho about inlining
  • When inlining in CorePrep we use cpe_ExprIsTrivial, which treats all literals (including strings) as trivial and hence inlinable. No one quite knows why: see #11158

So the best path forward seems to be to fix #11158, which we want to do anyway. Then we won't duplicate string literals, and bytestring will probably be happy again.

comment:8 Changed 13 months ago by Ben Gamari <ben@…>

In b5460dd/ghc:

Add testcase for #12757

Test Plan: Validate, expected to fail

Reviewers: austin

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D2665

GHC Trac Issues: #12757

comment:9 Changed 13 months ago by bgamari

Resolution: fixed
Status: newclosed

#11158 has been resolved. The fix was merged to ghc-8.0 as 58d9f9b7a7f1b4d2c94183b9b9428983e7c83fe9.

Last edited 13 months ago by bgamari (previous) (diff)

comment:10 Changed 13 months ago by bgamari

Sadly I made a silly mistake in the 8.0.2-rc1 source release; it turns out that the commit fixing #11158 didn't quite make it into the release. Consequently slyfox reported another similar issue, #12855, which is also fixed by merging the #11158 fix.

Note: See TracTickets for help on using tickets.