【问题标题】:Why provide the `HasCallStack` mechanism since we already have `ghc -prof -fprof-auto-top` in GHC?既然我们在 GHC 中已经有了 ghc -prof -fprof-auto-top ,为什么还要提供 `HasCallStack` 机制?
【发布时间】:2019-10-31 15:22:54
【问题描述】:

AFAIK,有两种方法可以在 Haskell 中获取用于调试的调用堆栈:

  1. 在代码中添加HasCallStack约束
  2. ghc -prof -fprof-auto-top编译代码

我的测试代码:

import GHC.Stack

-- | a wrapper function to make "last" from base traceable
last' :: HasCallStack => [a] -> a
last' xs = case xs of [] -> error "abuse last"; _ -> last xs

-- | a untraceable partial function
foo :: [Int] -> Int
foo xs = last' xs + 1

-- | a untraceable partial function
-- , which looks like traceable, but it's call stack is cut off by "foo"
bar :: HasCallStack => [Int] -> Int
bar xs = foo xs

-- | an empty list
-- , which is also an improper input of "last'"
xs :: [Int]
xs = []

-- | the program is expected to print a call stack telling how "bar" is called
-- , but we can only know that "foo" called "last'" improperly from the printed call stack
main :: IO ()
main = print $ bar xs

以下是我通过this测试代码从以上两种方式得到的调用栈:

$ ghc -prof -fprof-auto call-stack-cut-off.hs
$ ./call-stack-cut-off
call-stack-cut-off: abuse last
CallStack (from HasCallStack):
  error, called at call-stack-cut-off.hs:5:29 in main:Main
  last', called at call-stack-cut-off.hs:9:10 in main:Main
CallStack (from -prof):
  Main.last' (call-stack-cut-off.hs:5:1-60)
  Main.foo (call-stack-cut-off.hs:9:1-21)
  Main.bar (call-stack-cut-off.hs:14:1-15)
  Main.main (call-stack-cut-off.hs:24:1-21)
  Main.CAF (<entire-module>)

IMO,来自-prof 的调用堆栈已经足够好并且更易于使用。所以我想知道为什么还要添加HasCallStack 机制。这两种方式之间是否存在一些会显着影响调试体验的差异?

【问题讨论】:

    标签: haskell ghc callstack


    【解决方案1】:

    HasCallStack 有几个基本优势:

    1. 它更轻量级,不需要-prof,因此不需要重新编译(因为已分析的代码与未分析的代码具有不同的 ABI)

    2. 根据您放置 HasCallStack 约束的位置和使用 withFrozenCallStack 的位置,您可以更好地控制调用堆栈中包含的内容,以防止无关/内部细节出现在跟踪中

    3. 它允许您使用 getCallStack 从程序本身内部访问调用堆栈,因此您可以将其合并到用于日志记录、异常等的消息中

    【讨论】:

    • 第 1 点有点误导:如果你添加了HasCallStack,你肯定需要重新编译才能生效。我认为你的意思是你不需要像打开分析时那样重新编译其他所有东西(其他模块和库)。
    猜你喜欢
    • 2015-02-15
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    • 1970-01-01
    • 2017-11-13
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    相关资源
    最近更新 更多