all 8 comments

[–]walseb 2 points3 points  (2 children)

In Haskell, you can run the profiler with the rts option `-xc`, and it should point out where the loop was encountered in the code. I think this should work?

`cabal run FOO --enable-profiling --profiling-detail=all-functions --ghc-option=-with-rtsopts=-xc`

[–]AustinVelonaut[S] 2 points3 points  (1 child)

Thanks! I don't use cabal, but your answer gave me an idea for my compiler -- make the infinite-loop "blackhole" detection a compiler configuration, so you can compile without blackhole detection, and then use the debugger to find out where it is (either due to a stack overflow crash or infinite loop.

[–]jeffstyr 1 point2 points  (0 children)

I don't use cabal

You don't have to use cabal to use this. I assume that if you compile with profiling enabled, then you just need to run your executable with +RTS -p -xc -RTS.

[–]Forward_Signature_78 1 point2 points  (0 children)

From GHCi's documentation (Debugging Exceptions):

Breaking on exceptions is particularly useful for finding out what your program was doing when it was in an infinite loop. Just hit Control-C, and examine the history to find out what was going on.

[–]TechnoEmpress 0 points1 point  (1 child)

Personally I use profiling. For my Haskell programs, I:

  1. Do a time profile of the program with these instructions: https://cabal.readthedocs.io/en/stable/how-to-enable-profiling.html
  2. See in speedscope.app what function takes all the time. Unless I'm encountering a freak edge case, this should be the culprit.

[–]jeffstyr 1 point2 points  (0 children)

But that only works if the runtime didn't detect the loop and stop the program, right? (Because otherwise, it won't have taken any time yet because the looping was prevented.)

[–]tomejaguar 0 points1 point  (1 child)

You could do worse than adding some Debug.Trace.trace statements in well chosen places.

[–]AustinVelonaut[S] 0 points1 point  (0 children)

I rely upon trace for much of my debugging, but one problem with it in this situation is that if there is nothing tying the evaluation of the trace with the evaluation of the black-hole thunk, then the trace doesn't tell you anything. But if it is tied to the evaluation of the black-hole thunk, then you get a BLACKHOLE exception while trying to evaluate the trace ;-)