Отстраняване на грешки/влизане в пакетен модул чрез 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 и след това добавя следните два реда към моя 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 файл с моя cabal файл по-горе, което се чувства малко прекомерно.

Има ли по-лесен начин да задам точка на прекъсване в Criterion, така че да мога да премина (при отстраняване на грешки в cabal repl/ghci) директно от моя източник в източника на критерия? Благодаря

p.s. Има свързан въпрос в Отстраняване на грешки в IO в пакетен модул в GHCi, но за съжаление не помогна.


person artella    schedule 06.04.2015    source източник
comment
Не знам отговора на частта от файла cabal, но доколкото знам, GHCi може само да дебъгва код във вътрешния си формат на байт код. По-конкретно, искате да избегнете естествено компилиране с cabal build, тъй като получените .o файлове ще се използват по подразбиране вместо байт код.   -  person Ørjan Johansen    schedule 07.04.2015
comment
@ØrjanJohansen Благодаря, успях да отстраня грешки в маниока преди, като обединих файловете на cabal, което ми позволи безпроблемно да премина от моето приложение към маниока. Същите опити с критерий обаче водят до 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. Така че за момента мога да постигна желаното поведение чрез обединяване на cabal файловете и добавяне на cc-options: -fPIC към получения cabal файл.   -  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
    

    Тогава пълният файл на 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 = _
    
person artella    schedule 08.04.2015