为了分析部分评估的程序,我有兴趣了解终止GHC程序的最佳方法.这对于分析需要很长时间才能运行的程序非常有用,可能只需要永久运行.
使用GHC 7.4.2,我能够通过启用分析(-prof -auto-all)和运行我的程序来分析非终止程序+RTS -p.这会生成增量分析数据.该程序可能会被杀死^c,而.prof文件将包含数据.在GHC 7.6及更高版本中,似乎如果程序可以用单个^ c终止,则将分析信息写入输出.然而(特别是对于更新版本的GHC?)单个^ c不会杀死程序,至少在我不耐烦之前并再次点击^ c.通常两个^ c将终止程序,但之后没有将分析数据写入输出.
具体来说,请考虑尝试分析StupidFib.hs的问题:
fib n = fib (n - 1) + fib (n - 2)
main = print $ fib 100
Run Code Online (Sandbox Code Playgroud)
使用-prof进行编译并使用+ RTS -p运行,我可以在执行的第一个大约10秒内使用单个 ^ c 终止此程序,但之后只有两个^ c将执行该作业.看看我的资源,这个变化似乎与使用我所有物理内存并转移到交换空间的程序一致,但这可能是巧合.
为什么^ c有时会工作,而不是同一个程序的其他时间?当程序没有自行终止时,确保分析数据打印的最简单方法是什么?
我的程序中某处有一个无限循环,导致<<loop>>正常运行时出现异常.使用GHCi,我已经将问题追踪到了thunk
f = Constructor1
(Constructor2 A :
(_t3::[DataType2]))
Run Code Online (Sandbox Code Playgroud)
试图对thunk进行排序seq _t3 ()导致GHCi挂起,所以如果我理解正确的话,无限循环正在减少到弱头正常形式.有没有办法调查这个thunk,例如,逐步看到试图用来评估它的减少步骤?
这个问题基本上是使用GHCi在Haskell程序中调试无限循环的重复.那里的作者手动解决了它,虽然我想知道其他解决方案.
我有一个包含递归调用的箭头代码,
testAVFunctor = proc x -> do
y <- errorArrow "good error" -< x
z <- isError -< y
(passError ||| testAVFunctor) -< trace "value of z" z
Run Code Online (Sandbox Code Playgroud)
本errorArrow应使递归testAVFunctor无法执行,因为这将导致ISERROR返回一个Left (AVError "good error")应依次选择passError路由,绕过递归调用.
非常奇怪的是,在功能组合等热门网站上插入"跟踪"调用会导致程序发出有限量的输出,然后冻结.不是我对无限期扩张问题的期望.(见编辑1)
如果有人这么好奇我在这里上传了我的源代码.
我没有找到正确的地方(如果你想看看源,显然avEither正在循环).我到那里的方法是编译二进制文件,然后运行gdb:
您可以使用ghc标志-O0进行编译以禁用优化,这可以显示更多方法名称.
显然,proc x -> do上面的块导致代码生成组合器,组合器调用AVFunctor.arr …