Отладка/вход в пакетный модуль через cabal repl

Итак, у меня есть следующий код из Предотвращение кэширования вычислений в тесте Criterion, и моя цель - иметь возможность перейти от main непосредственно к функция defaultMain в Criterion.Main :

{-# 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) ()]
  ]

и файл кабалы:

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, а затем добавлю следующие две строки в мой файл клики:

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)

поэтому я подозреваю, что мне нужно выполнить полное слияние файла клики критерия с моим файлом клики выше, что кажется немного чрезмерным.

Есть ли более простой способ установить точку останова в Criterion, чтобы я мог перейти (при отладке в cabal repl/ghci) прямо из моего источника в источник критерия? Спасибо

p.s. Есть связанный с этим вопрос в разделе Отладка ввода-вывода в модуле пакета внутри GHCi, но, к сожалению, это не помогло.


person artella    schedule 06.04.2015    source источник
comment
Я не знаю ответа на часть файла cabal, но, насколько мне известно, GHCi может только отлаживать код в своем внутреннем формате байт-кода. В частности, вы хотите избежать собственной компиляции с cabal build, так как результирующие файлы .o будут использоваться по умолчанию вместо байт-кода.   -  person Ørjan Johansen    schedule 07.04.2015
comment
@ØrjanJohansen Спасибо, раньше мне удавалось отлаживать маниоку, объединяя файлы клики, что позволило мне плавно перейти от моего приложения к маниоке. Однако те же попытки с критерием приводят к 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, что я сейчас и пытаюсь решить!   -  person artella    schedule 07.04.2015
comment
@ØrjanJohansen: Ах, кажется, способ устранить ошибку time-posix.o в комментарии выше — это добавить параметр cc-options: -fPIC. Итак, на данный момент я могу добиться желаемого поведения, объединив файлы кликов и добавив cc-options: -fPIC к полученному файлу кликов.   -  person artella    schedule 07.04.2015
comment
Большой! Это звучит как полезный совет. Если вы хотите, вы можете опубликовать ответ на свой вопрос, описав, как вы его решили.   -  person Ørjan Johansen    schedule 07.04.2015
comment
@ØrjanJohansen: я разместил метод ниже. Спасибо.   -  person artella    schedule 08.04.2015


Ответы (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, создайте файл Main.hs, содержащий приведенный выше код теста, а также приведенный выше файл Cabal, но объедините его с файлом Cabal критерия, содержащимся в /tmp/testCrit/criterion-1.1.0.0, следующим образом. Обратите внимание, что основными новыми дополнениями являются строки:

    cc-options: -fPIC
    

    что позволяет запускать его в cabal repl и следующих строках:

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

    Полный файл клики должен выглядеть так:

      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 = _
    
person artella    schedule 08.04.2015