Tritlo / PropR

Genetic program repair using GHC
MIT License
30 stars 2 forks source link

Segmentation fault on OS X #3

Closed lapplislazuli closed 3 years ago

lapplislazuli commented 3 years ago

Trying to run it on my macbook gives me the following:

(base) TUD500590:HenProg lapplis$ cabal run henprog -- tests/BrokenModule.hs
Resolving dependencies...
Up to date
TARGET:
  `broken` in tests/BrokenModule.hs
SCOPE:
  import Prelude hiding (id, ($), ($!), asTypeOf)
TARGET TYPE:
  [Int] -> Int
MUST SATISFY:
  prop'_isSum broken xs = broken xs == sum xs
IN CONTEXT:
  prop_isSum :: [Int] -> Bool
  broken :: [Int] -> Int
  add :: Int -> Int -> Int
  main :: IO ()
  prop_isSum xs = broken xs == sum xs
  broken = foldl (-) 0
  add = (+)
  main = print "Unrelated main function"
PARAMETERS:
  MAX HOLES: 2
  MAX DEPTH: 1
PROGRAM TO REPAIR: 
let
  broken :: [Int] -> Int
  broken = foldl (-) 0
in broken
REPAIRING...
Segmentation fault: 11
~/HenProg lapplis$ cabal run henprog -- tests/BrokenGCD.hs
Up to date
TARGET:
  `gcd'` in tests/BrokenGCD.hs
SCOPE:
  import Prelude hiding (id, ($), ($!), asTypeOf)
TARGET TYPE:
  Int -> Int -> Int
MUST SATISFY:
  prop'_1 gcd' = gcd' 0 55 == 55
  prop'_2 gcd' = gcd' 1071 1029 == 21
  prop'_3 gcd' a b = gcd' (abs a) (abs b) == gcd (abs a) (abs b)
IN CONTEXT:
  add :: Int -> Int -> Int
  zero :: Int
  one :: Int
  gcd' :: Int -> Int -> Int
  main :: IO ()
  add = (+)
  zero = 0
  one = 1
  prop_1 = gcd' 0 55 == 55
  prop_2 = gcd' 1071 1029 == 21
  prop_3 a b = gcd' (abs a) (abs b) == gcd (abs a) (abs b)
  gcd' 0 b = gcd' 0 b
gcd' a b | b == 0 = a
gcd' a b = if (a > b) then gcd' (a - b) b else gcd' a (b - a)
  main = print "Unrelated main function"
PARAMETERS:
  MAX HOLES: 2
  MAX DEPTH: 1
PROGRAM TO REPAIR: 
let
  gcd' :: Int -> Int -> Int
  gcd' 0 b = gcd' 0 b
  gcd' a b | b == 0 = a
  gcd' a b = if (a > b) then gcd' (a - b) b else gcd' a (b - a)
in gcd'
REPAIRING...
Segmentation fault: 11

I get the same issue with the BrokenModule.hs.

I installed QuickCheck Manually beforehand doing cabal install --lib QuickCheck.

Altering the command to cabal run henprog -- tests/BrokenModule.hs -fdebug or cabal run henprog -- -fdebug tests/BrokenModule.hs does not produce additional output.

GHC: 8.10.1 Cabal: 3.2.0.0 MacOS: Big Sur 13.1.1

Tritlo commented 3 years ago

Oh wow, that should not happen in Haskell haha. I'll look into it!

On Fri, 7 May 2021 at 10:18, L. Applis @.***> wrote:

Trying to run it on my macbook gives me the following:

(base) TUD500590:HenProg lapplis$ cabal run henprog -- tests/BrokenModule.hs Resolving dependencies... Up to date TARGET: broken in tests/BrokenModule.hs SCOPE: import Prelude hiding (id, ($), ($!), asTypeOf) TARGET TYPE: [Int] -> Int MUST SATISFY: prop'_isSum broken xs = broken xs == sum xs IN CONTEXT: prop_isSum :: [Int] -> Bool broken :: [Int] -> Int add :: Int -> Int -> Int main :: IO () prop_isSum xs = broken xs == sum xs broken = foldl (-) 0 add = (+) main = print "Unrelated main function" PARAMETERS: MAX HOLES: 2 MAX DEPTH: 1 PROGRAM TO REPAIR: let broken :: [Int] -> Int broken = foldl (-) 0 in broken REPAIRING... Segmentation fault: 11 ~/HenProg lapplis$ cabal run henprog -- tests/BrokenGCD.hs Up to date TARGET: gcd' in tests/BrokenGCD.hs SCOPE: import Prelude hiding (id, ($), ($!), asTypeOf) TARGET TYPE: Int -> Int -> Int MUST SATISFY: prop'_1 gcd' = gcd' 0 55 == 55 prop'_2 gcd' = gcd' 1071 1029 == 21 prop'_3 gcd' a b = gcd' (abs a) (abs b) == gcd (abs a) (abs b) IN CONTEXT: add :: Int -> Int -> Int zero :: Int one :: Int gcd' :: Int -> Int -> Int main :: IO () add = (+) zero = 0 one = 1 prop_1 = gcd' 0 55 == 55 prop_2 = gcd' 1071 1029 == 21 prop_3 a b = gcd' (abs a) (abs b) == gcd (abs a) (abs b) gcd' 0 b = gcd' 0 b gcd' a b | b == 0 = a gcd' a b = if (a > b) then gcd' (a - b) b else gcd' a (b - a) main = print "Unrelated main function" PARAMETERS: MAX HOLES: 2 MAX DEPTH: 1 PROGRAM TO REPAIR: let gcd' :: Int -> Int -> Int gcd' 0 b = gcd' 0 b gcd' a b | b == 0 = a gcd' a b = if (a > b) then gcd' (a - b) b else gcd' a (b - a) in gcd' REPAIRING... Segmentation fault: 11

I get the same issue with the BrokenModule.hs.

I installed QuickCheck Manually beforehand doing cabal install --lib QuickCheck.

Altering the command to cabal run henprog -- tests/BrokenModule.hs -fdebug or cabal run henprog -- -fdebug tests/BrokenModule.hs does not produce additional output.

GHC: 8.10.1 Cabal: 3.2.0.0 MacOS: Big Sur 13.1.1

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Tritlo/HenProg/issues/3, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMXBV7532H3GNZJ2SUYAJDTMO5ADANCNFSM44JPDSAA .

-- Bestu Kveðjur/Best regards, Matthías Páll Gissurarson.

lapplislazuli commented 3 years ago

Here is the Debug Log HenProgDebug.log

My guts tell me it's somewhere with the Caching.

Tritlo commented 3 years ago

@lapplislazuli that file just contains "Up to date"... maybe you only redirected the error output? I need the stdout as well.

lapplislazuli commented 3 years ago

That's funny actually, sorry. Seems that when I pipe it > henprog.log it just puts the cabal output there.

here is the actual output:

 cabal run henprog -- tests/BrokenModule.hs --log=debug

Leads to:

Up to date
TARGET:
  `broken` in tests/BrokenModule.hs
SCOPE:
  import Prelude hiding (id, ($), ($!), asTypeOf)
TARGET TYPE:
  [Int] -> Int
MUST SATISFY:
  prop'_isSum broken xs = broken xs == sum xs
IN CONTEXT:
  prop_isSum :: [Int] -> Bool
  broken :: [Int] -> Int
  add :: Int -> Int -> Int
  main :: IO ()
  prop_isSum xs = broken xs == sum xs
  broken = foldl (-) 0
  add = (+)
  main = print "Unrelated main function"
PARAMETERS:
  MAX HOLES: 2
  MAX DEPTH: 1
PROGRAM TO REPAIR: 
let
  broken :: [Int] -> Int
  broken = foldl (-) 0
in broken
REPAIRING...
AUDIT: 79ms
DEBUG:   (let
     broken :: [Int] -> Int
     broken = foldl (-) 0
   in broken) ::
    [Int] -> Int
DEBUG: [(<no location info>, _<no location info>),
 (<no location info>, _<no location info> :: [Int] -> Int),
 (<no location info>, (_<no location info>) :: [Int] -> Int),
 (tests/BrokenModule.hs:8:10-20,
    (let
       broken :: [Int] -> Int
       broken = _8_10_21
     in broken) ::
      [Int] -> Int),
 (tests/BrokenModule.hs:8:10-18,
    (let
       broken :: [Int] -> Int
       broken = _8_10_19 0
     in broken) ::
      [Int] -> Int),
 (tests/BrokenModule.hs:8:10-14,
    (let
       broken :: [Int] -> Int
       broken = _foldl8_10_15 (-) 0
     in broken) ::
      [Int] -> Int),
 (tests/BrokenModule.hs:8:16-18,
    (let
       broken :: [Int] -> Int
       broken = foldl _-8_16_19 0
     in broken) ::
      [Int] -> Int),
 (tests/BrokenModule.hs:8:20,
    (let
       broken :: [Int] -> Int
       broken = foldl (-) _8_20_21
     in broken) ::
      [Int] -> Int),
 (<no location info>,
    (let
       broken :: [Int] -> Int
       broken = foldl (-) 0
     in _broken<no location info>) ::
      [Int] -> Int)]
Segmentation fault: 11
Tritlo commented 3 years ago

Hmm, maybe. Could you try and add some logStr "HERE" to track down where exactly it happens? It's a bit hard for me to figure out, since I can't run it on a Mac.

lapplislazuli commented 3 years ago

These are the last parts it touches before the segfault.

https://github.com/Tritlo/HenProg/blob/2ad47d80aa7f7576325d6e5cbf6a1f6372f2e334/src/Synth/Eval.hs#L153-L187

I tried to get more info by adding let p = unsafePerformIO $ logStr DEBUG "Ping" but I can't see them, is that an error on my side? How can I get more info from in there?

Tritlo commented 3 years ago

The logStr DEBUG displays when --log-level=DEBUG, did you have that flag open?

This is a very basic place to get a SegFault, we're not even doing anything there!

On Thu, 20 May 2021 at 17:01, L. Applis @.***> wrote:

These are the last parts it touches before the segfault.

https://github.com/Tritlo/HenProg/blob/2ad47d80aa7f7576325d6e5cbf6a1f6372f2e334/src/Synth/Eval.hs#L153-L187

I tried to get more info by adding let p = unsafePerformIO $ logStr DEBUG "Ping" but I can't see them, is that an error on my side? How can I get more info from in there?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Tritlo/HenProg/issues/3#issuecomment-845199718, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMXBV4ZC3F4QIHJLEJ4WKDTOUP6HANCNFSM44JPDSAA .

-- -- Matthías Páll Gissurarson http://mpg.is/

lapplislazuli commented 3 years ago

Ok so I had another look at it, and the InitGhcCtxt' is run 3 times (fully succesfull, atleast every marks are run) and then it fails further upstream. It also persists in the improved-genetic-parts branch, so I'll be looking there for it.

the trace goes

main -> genetic search -> initialpopulation -> repairattempt -> Either ( failingProps) or (collectStats)

In collect stats, it does weird stuff

"instrumented" CollectStats

collectStats :: (MonadIO m, HasCallStack) => m a -> m a
collectStats a = do
  liftIO $ putStrLn "1"
  (t, r) <- time a
  liftIO $ putStrLn "2"
  let ((_, GHS.SrcLoc {..}) : _) = getCallStack callStack
  liftIO $ putStrLn "3"
  liftIO $ modifyIORef statsRef (Map.insertWith (+) (srcLocFile, srcLocStartLine) t)
  liftIO $ putStrLn "4"
  withFrozenCallStack $ liftIO $ logStr AUDIT (showTime t)
  liftIO $ putStrLn "5"
  return r

output

[... as above...]
REPAIRING...
1
2
3
4
5
1
1
Segmentation fault: 11

Another place is

-- | Returns the props that fail for the given program
failingProps :: CompileConfig -> EProblem -> IO [EProp]
failingProps _ EProb {e_props = []} = return []
-- Our method for checking which props fail is restricted to maximum 8 at a time,
-- so if we have more than that, we check the first 8 and then the rest, and
-- so on.
failingProps cc rp@EProb {e_props = ps} | length ps > 8 = do
  putStrLn "A1"
  let (ps1, ps2) = splitAt 8 ps
  putStrLn "B1"
  p1 <- failingProps cc rp {e_props = ps1}
  putStrLn "C1"
  p2 <- failingProps cc rp {e_props = ps2}
  putStrLn "D1"
  return (p1 ++ p2)
failingProps cc ep@EProb {..} = do

  putStrLn "A2"
  let cc' = (cc {hole_lvl = 0, importStmts = checkImports ++ importStmts cc})
      check = buildSuccessCheck ep
  putStrLn "B2"
  [compiled_check] <- compileParsedChecks cc' [check]

  putStrLn "C2"
  ran <- runCheck compiled_check
  putStrLn "D2"
  case ran of
    -- Some of the props are failing:
    Left p -> return $ map fst $ filter (\(p, c) -> not c) $ zip e_props p
    -- None of the props are failing:
    Right True -> return []
    -- One of the props is causing an error/infinite loop, so we need
    -- to check each individually
    Right False ->
      case e_props of
        -- If there's only one failing prop left, that's the one causing
        -- the loop
        [prop] -> return [prop]
        -- Otherwise, we split the props into two sets, and check each
        -- split individually.
        xs -> do
          let fp :: [EProp] -> IO [EProp]
              fp ps = failingProps cc ep {e_props = ps}
              ps1, ps2 :: [EProp]
              (ps1, ps2) = splitAt (length e_props `div` 2) e_props
          concat <$> mapM fp [ps1, ps2]

Which leads to (with the one above)

[... as above...]
REPAIRING...
1
2
3
4
5
1
1
A2
B2
Segmentation fault: 11
lapplislazuli commented 3 years ago

Oh wow, my google fu is strong today. I just ran

cabal configure --enable-optimization --enable-executable-dynamic 

in project root after reading this bug https://github.com/haskell/haskell-language-server/issues/469 . It works now, finding solutions and being nice.

let's close this after adding something about it in the Readme.

lapplislazuli commented 3 years ago

We made a remark in the README and in the Relase - should be good.