24

If we get a <<loop>>, it means that Haskell had managed to detect an infinite loop. Is there a way to get ghc to tell us where this loop happened? It seems that Haskell should have this information somewhere.

Bakuriu
  • 98,325
  • 22
  • 197
  • 231
yong
  • 3,583
  • 16
  • 32

2 Answers2

26

Compile your app with -prof and -fprof-auto(if you're using Cabal, use --enable-executable-profiling and --ghc-options=-fprof-auto) and then run it with +RTS -xc. It'll print a stack trace when errors happen. This should help you narrow your scope.

Example:

➜  haskell  cat loop.hs 
myFun :: Int
myFun =
    let g = g + 1
    in g + 10

main = print myFun
➜  haskell  ghc loop.hs -prof -fprof-auto
[1 of 1] Compiling Main             ( loop.hs, loop.o )
Linking loop ...
➜  haskell  ./loop +RTS -xc                             
*** Exception (reporting due to +RTS -xc): (THUNK_STATIC), stack trace: 
  Main.myFun.g,
  called from Main.myFun,
  called from Main.CAF
*** Exception (reporting due to +RTS -xc): (THUNK_STATIC), stack trace: 
  Main.myFun.g,
  called from Main.myFun,
  called from Main.CAF
loop: <<loop>>
sinan
  • 6,809
  • 6
  • 38
  • 67
1

In addition to what has already been written: These loops are only detected at run-time. The detection is based on the code attempting to evaluate a value which is already being evaluated [by the same thread]. Clearly that should never happen.

If you're looking for a compiler switch to detect this at compile-time... you're out of luck. It's easy enough to statically spot recursion, but deciding whether the recursion is infinite or not isn't so easy.

MathematicalOrchid
  • 61,854
  • 19
  • 123
  • 220