【问题标题】:Debugging/Stepping into a package module via cabal repl通过 cabal repl 调试/步入包模块
【发布时间】:2015-04-06 19:00:01
【问题描述】:

所以我有来自Preventing caching of computation in Criterion benchmark 的以下代码,我的目标是能够从main 直接进入Criterion.Main 中的函数defaultMain

{-# OPTIONS -fno-full-laziness #-}
{-# OPTIONS_GHC -fno-cse #-}
{-# LANGUAGE BangPatterns #-}
module Main where
import Criterion.Main
import Data.List

num :: Int
num = 100000000

lst :: a -> [Int]
lst _ = [1,2..num]

myadd :: Int -> Int -> Int
myadd !x !y = let !result = x + y in
  result

mysum = foldl' myadd 0

main :: IO ()
main = defaultMain [
  bgroup "summation" 
    [bench "mysum" $ whnf (mysum . lst) ()]
  ]

而 cabal 文件是:

name:                test
version:             0.1.0.0
build-type:          Simple
cabal-version:       >=1.10

executable test
  main-is:             Main.hs
  build-depends:       base >=4.8 && <4.9,
                       criterion==1.1.0.0
  default-language:    Haskell2010
  ghc-options:         "-O3"

(使用 ghc 7.10.1 和 cabal 1.22.0.0)。

如果在cabal repl 中尝试在标准中设置断点,则会收到以下错误:

*Main> :break Criterion.Main.defaultMain
cannot set breakpoint on defaultMain: module Criterion.Main is not interpreted

此外,如果我尝试add 包,我会收到以下错误:

*Main> :add *Criterion

<no location info>: module ‘Criterion’ is a package module
Failed, modules loaded: Main.

如果我在目录git clone https://github.com/bos/criterion 然后将以下两行添加到我的 cabal 文件中:

other-modules:       Criterion
hs-source-dirs:      .
                 ./criterion

然后在执行cabal build 时出现以下错误:

criterion/Criterion/IO.hs:23:0:
     error: missing binary operator before token "("
     #if MIN_VERSION_binary(0, 6, 3)

所以我怀疑我必须完全合并标准阴谋集团 上面我的cabal文件,感觉有点过分了。

有没有更简单的方法来设置断点 在 Criterion 中,以便我可以(在 cabal repl/ghci 中调试时)直接从我的源代码进入标准的源代码?谢谢

附言Debugging IO in a package module inside GHCi 有一个相关问题,但不幸的是它没有帮助。

【问题讨论】:

  • 我不知道cabal 文件部分的答案,但据我所知,GHCi 只能 调试其内部字节码格式的代码。特别是,您要避免使用 cabal build 进行本机编译,因为默认情况下将使用生成的 .o 文件而不是字节码。
  • @ØrjanJohansen 谢谢,我之前通过“合并” cabal 文件设法调试了 cassava,这让我可以无缝地从我的应用程序进入 cassava。然而,与标准相同的尝试会导致criterion-1.1.0.0/cbits/time-posix.o: relocation R_X86_64_PC32 against undefined symbol clock_gettime@@GLIBC_2.2.5 can not be used when making a shared object; recompile with -fPIC,这是我目前正在尝试解决的问题!
  • @ØrjanJohansen :啊,解决上面评论中time-posix.o错误的方法似乎是添加选项cc-options: -fPIC。所以目前我可以通过合并 cabal 文件并将cc-options: -fPIC 添加到生成的 cabal 文件中来实现所需的行为。
  • 太棒了!这听起来确实是一个普遍有用的提示。如果您愿意,您可以发布自己的问题的答案,描述您是如何解决的。
  • @ØrjanJohansen :我发布了下面的方法。谢谢。

标签: debugging haskell ghc cabal ghci


【解决方案1】:

这就是我如何设法实现能够(在cabal repl 内)从我的代码进入标准源的预期目标:

  1. 先做:

    mkdir /tmp/testCrit
    cd /tmp/testCrit
    
  2. 下载criterion-1.1.0.0.tar.gz

  3. 解压到/tmp/testCrit,所以我们应该有/tmp/testCrit/criterion-1.1.0.0。在这个目录中,我们有 Criterion.hs 等。

  4. 然后跳转到包含标准源的文件夹并执行:

    cd /tmp/testCrit/criterion-1.1.0.0
    cabal sandbox init
    cabal install -j
    

    请注意,这会创建一个目录:/tmp/testCrit/criterion-1.1.0.0/dist/dist-sandbox-782e42f0/build/autogen,我们稍后将使用它

  5. 返回/tmp/testCrit 创建一个包含上述基准代码和上述cabal 文件的Main.hs 文件,但将其与/tmp/testCrit/criterion-1.1.0.0 中包含的标准cabal 文件以下列方式合并。注意主要的新增内容是以下几行:

    cc-options: -fPIC
    

    它允许在cabal repl 中运行它,以及以下 行:

    hs-source-dirs: 
      ./
      ./criterion-1.1.0.0
      ./criterion-1.1.0.0/dist/dist-sandbox-782e42f0/build/autogen
    

    完整的 cabal 文件应如下所示:

      name:                test
      version:             0.1.0.0
      build-type:          Simple
      cabal-version:       >=1.10
    
      executable test
        main-is:             Main.hs
        build-depends:       
          base >=4.8 && <4.9,
          aeson >= 0.8,
          ansi-wl-pprint >= 0.6.7.2,
          base >= 4.5 && < 5,
          binary >= 0.5.1.0,
          bytestring >= 0.9 && < 1.0,
          cassava >= 0.3.0.0,
          containers,
          deepseq >= 1.1.0.0,
          directory,
          filepath,
          Glob >= 0.7.2,
          hastache >= 0.6.0,
          mtl >= 2,
          mwc-random >= 0.8.0.3,
          optparse-applicative >= 0.11,
          parsec >= 3.1.0,
          statistics >= 0.13.2.1,
          text >= 0.11,
          time,
          transformers,
          transformers-compat >= 0.4,
          vector >= 0.7.1,
          vector-algorithms >= 0.4
        default-language:    Haskell2010
        ghc-options:         "-O3"
        c-sources: 
          ./criterion-1.1.0.0/cbits/cycles.c
          ./criterion-1.1.0.0/cbits/time-posix.c
        hs-source-dirs: 
          ./
          ./criterion-1.1.0.0
          ./criterion-1.1.0.0/dist/dist-sandbox-782e42f0/build/autogen
        cc-options: -fPIC
    
  6. 然后在主目录中做:

    cd /tmp/testCrit/
    cabal sandbox init
    cabal install -j
    
  7. 然后我们可以启动cabal repl 并直接进入 标准来自我们的Main.hs 代码

    *Main> :break Criterion.Main.defaultMain
    Breakpoint 0 activated at criterion-1.1.0.0/Criterion/Main.hs:79:15-43
    *Main> main
    Stopped at criterion-1.1.0.0/Criterion/Main.hs:79:15-43
    _result :: [Benchmark] -> IO () = _
    [criterion-1.1.0.0/Criterion/Main.hs:79:15-43] *Main> :step
    Stopped at criterion-1.1.0.0/Criterion/Main.hs:(131,1)-(147,39)
    _result :: IO () = _
    [criterion-1.1.0.0/Criterion/Main.hs:(131,1)-(147,39)] *Main> :step
    Stopped at criterion-1.1.0.0/Criterion/Main.hs:(131,29)-(147,39)
    _result :: IO () = _
    bs :: [Benchmark] = [_]
    defCfg :: Criterion.Types.Config = _
    [criterion-1.1.0.0/Criterion/Main.hs:(131,29)-(147,39)] *Main> :step
    Stopped at criterion-1.1.0.0/Criterion/Main.hs:132:10-37
    _result :: IO Criterion.Main.Options.Mode = _
    defCfg :: Criterion.Types.Config = _
    

【讨论】:

    猜你喜欢
    • 2022-07-26
    • 1970-01-01
    • 2014-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    相关资源
    最近更新 更多