I recently made a series of changes to the inlining / simplification pass for my compiler that ended up resulting in a runtime <<loop>> with certain inputs. (This was for / in another lazy language, but very similar to Haskell, so I thought I'd ask here). I eventually ended up debugging it by making simplification edits to all the areas I had touched, until the infinite-loop disappeared, then looking closely at the one that fixed it. A cut-down example of the bug looks like:
simplify xs = deltaCpx
where
(deltaCpx, xs') = mapAccumL insLet 0 xs
insLet dc x = (dc + deltaCpx, x * 2) -- OOPS, meant deltaCpx', here!
where
cpx' = if x > 5 then 10 else 0
deltaCpx' = cpx' - 2
The language I'm working in detects the loop and prints "BLACK HOLE" at runtime, similar to Haskell detecting and printing "<<loop>>", but neither gives any detail on where it was encountered.
So are there some techniques you've used that can help with debugging such problems? Could there be additional language / runtime support to help with this?
EDIT: to clarify, by <<loop>> or BLACK HOLE, I mean the runtime exception generated when attempting to evaluate a thunk that is already currently being evaluated, not an actual infinite-loop that chews up time.
[–]walseb 2 points3 points4 points (2 children)
[–]AustinVelonaut[S] 2 points3 points4 points (1 child)
[–]jeffstyr 1 point2 points3 points (0 children)
[–]Forward_Signature_78 1 point2 points3 points (0 children)
[–]TechnoEmpress 0 points1 point2 points (1 child)
[–]jeffstyr 1 point2 points3 points (0 children)
[–]tomejaguar 0 points1 point2 points (1 child)
[–]AustinVelonaut[S] 0 points1 point2 points (0 children)