haskellhmatrix

Not able to print out call stack in haskell


I am getting the error:

nonconformable matrices in liftMatrix2Auto: (0x4), (4x1)
CallStack (from HasCallStack):
  error, called at src\Internal\Element.hs:488:19 in hmatrix-0.20.2-inplace:Internal.Element

How can I find - which line causes this error?

I don't call liftMatrix2Auto by myself.

I added (HasCallStack) => to main but it doesn't help - there is no call stack in the output.

I also added (HasCallStack) => to the functions running on other threads - didn't help.

Edits:

Tried to enable late-cost-center profiling with -xc runtime flag. It shows stack now, but without the line number:

CallStack (from -prof):
  Internal.Element.$wlvl3 (<no location info>)
  Internal.Element.$wliftMatrix2Auto (src\Internal\Element.hs:485:1-15)
  Main.newDuty (app\Main.hs:73:1-7)
  Main.$wlvl (<no location info>)
  Main.$wsensors (<no location info>)
  Main.$wlvl1 (<no location info>)
  Main.$wmain (<no location info>)
  Main.main3 (<no location info>)
  Main.main2 (<no location info>)
  Main.main (app\Main.hs:244:1-4)

The mentioned line numbers are actually the starting lines of the functions.

Edit

Tried to use the lower profiling-details. It added the first and the last line numbers for functions. Still have no error line number:

nonconformable matrices in liftMatrix2Auto: (0x4), (4x1)
CallStack (from HasCallStack):
  error, called at src\Internal\Element.hs:488:19 in hmatrix-0.20.2-inplace:Internal.Element  
CallStack (from -prof):
  Main.newDuty (app\Main.hs:(73,1)-(101,17))
  Main.sensors (app\Main.hs:(51,1)-(70,46))
  Main.main (app\Main.hs:(244,1)-(304,42))

Solution

  • GHC 9.10 has improved backtraces. You can now simply:

    1. Add a function in main:

      import Control.Exception.Backtrace
      
      main :: IO ()
      main = do
        setBacktraceMechanismState CostCentreBacktrace True
        ...
      

      (You can also put this deeper in your code if you know more precisely where the error might occur.)

    2. Run with profiling, e.g. cabal run --enable-profiling --ghc-options="-fprof-auto-calls".

    Here's a test file that I made:

    import Control.Exception.Backtrace
    
    top, mid, bot :: IO ()
    top = putStrLn "top" *> mid
    mid = putStrLn "mid" *> bot
    bot = putStrLn "bot" *> error "Foo"
    
    main :: IO ()
    main = setBacktraceMechanismState CostCentreBacktrace True *> top
    

    This is the result:

    top
    mid
    bot
    backtrace-test: Foo
    CallStack (from HasCallStack):
      error, called at app/Main.hs:6:25 in backtrace-test-0.1.0.0-inplace-backtrace-test:Main
    CallStack (from -prof):
      Main.bot (app/Main.hs:6:1-35)
      Main.mid (app/Main.hs:5:1-27)
      Main.top (app/Main.hs:4:1-27)
      Main.main (app/Main.hs:9:1-65)
    Cost-centre stack backtrace:
      Main.main (app/Main.hs:9:1-65)
      Main.top (app/Main.hs:4:1-27)
      Main.mid (app/Main.hs:5:1-27)
      Main.bot (app/Main.hs:6:1-35)
    HasCallStack backtrace:
      collectBacktraces, called at libraries/ghc-internal/src/GHC/Internal/Exception.hs:92:13 in ghc-internal:GHC.Internal.Exception
      toExceptionWithBacktrace, called at libraries/ghc-internal/src/GHC/Internal/Exception.hs:128:3 in ghc-internal:GHC.Internal.Exception
    
    
    
    

    Using GHC 9.12 you get less repetition although a bit too much detail at the end:

    top
    mid
    bot
    backtrace-test: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
    
    Foo
    
    Cost-centre stack backtrace:
      GHC.Internal.TopHandler.runMainIO1 (<no location info>)
      Main.main (app/Main.hs:9:1-65)
      Main.top (app/Main.hs:4:1-27)
      Main.mid (app/Main.hs:5:1-27)
      Main.bot (app/Main.hs:6:1-35)
      GHC.Internal.Err.error (libraries/ghc-internal/src/GHC/Internal/Err.hs:36:1-5)
      GHC.Internal.Exception.errorCallWithCallStackException (libraries/ghc-internal/src/GHC/Internal/Exception.hs:199:1-31)
      GHC.Internal.Stack.withFrozenCallStack (libraries/ghc-internal/src/GHC/Internal/Stack.hs:101:1-19)
      GHC.Internal.Exception.Backtrace.collectBacktraces (libraries/ghc-internal/src/GHC/Internal/Exception/Backtrace.hs:136:1-17)
      GHC.Internal.Exception.Backtrace.collectBacktraces1 (<no location info>)
      GHC.Internal.Exception.Backtrace.$wcollectBacktraces (<no location info>)
    HasCallStack backtrace:
      error, called at app/Main.hs:6:25 in backtrace-test-0.1.0.0-inplace-backtrace-test:Main
    
    
    
    

    A second issue seems to be that hmatrix uses -fno-prof-auto. I think the solution to this is just removing that option from the package. I've created a little reproducer repository for this issue:

    https://github.com/noughtmare/hmatrix-backtrace

    If you comment out the source-repository-package section in the cabal.project file and build it you should get a backtrace like this (I'm using GHC 9.12):

    $ cabal run --enable-profiling -v0
    hmatrix-backtrace: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
    
    nonconformable matrices in liftMatrix2Auto: (0x4), (4x1)
    
    Cost-centre stack backtrace:
      Main.CAF (<entire-module>)
      Main.main (app/Main.hs:(7,1)-(10,17))
      GHC.Internal.Err.error (libraries/ghc-internal/src/GHC/Internal/Err.hs:36:1-5)
      GHC.Internal.Exception.errorCallWithCallStackException (libraries/ghc-internal/src/GHC/Internal/Exception.hs:199:1-31)
      GHC.Internal.Stack.withFrozenCallStack (libraries/ghc-internal/src/GHC/Internal/Stack.hs:101:1-19)
      GHC.Internal.Exception.Backtrace.collectBacktraces (libraries/ghc-internal/src/GHC/Internal/Exception/Backtrace.hs:136:1-17)
      GHC.Internal.Exception.Backtrace.collectBacktraces1 (<no location info>)
      GHC.Internal.Exception.Backtrace.$wcollectBacktraces (<no location info>)
    HasCallStack backtrace:
      error, called at src/Internal/Element.hs:488:19 in hmatrix-0.20.2-f3d3a8739e608ed9c5ba25610f4dae57ab72d24b511e878387c40807cb85e3db:Internal.Element
    

    As you can see, there is no mention of a function from the hmatrix package in there. If you do use the source-repository-package (which just removes the -fno-prof-auto field) you get a more informative backtrace:

    $ cabal run --enable-profiling -v0
    hmatrix-backtrace: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
    
    nonconformable matrices in liftMatrix2Auto: (0x4), (4x1)
    
    Cost-centre stack backtrace:
      Main.CAF (<entire-module>)
      Main.main (app/Main.hs:(7,1)-(10,17))
      Internal.Element.liftMatrix2Auto (src/Internal/Element.hs:(485,1)-(498,29))
      GHC.Internal.Err.error (libraries/ghc-internal/src/GHC/Internal/Err.hs:36:1-5)
      GHC.Internal.Exception.errorCallWithCallStackException (libraries/ghc-internal/src/GHC/Internal/Exception.hs:199:1-31)
      GHC.Internal.Stack.withFrozenCallStack (libraries/ghc-internal/src/GHC/Internal/Stack.hs:101:1-19)
      GHC.Internal.Exception.Backtrace.collectBacktraces (libraries/ghc-internal/src/GHC/Internal/Exception/Backtrace.hs:136:1-17)
      GHC.Internal.Exception.Backtrace.collectBacktraces1 (<no location info>)
      GHC.Internal.Exception.Backtrace.$wcollectBacktraces (<no location info>)
    HasCallStack backtrace:
      error, called at src/Internal/Element.hs:488:19 in hmatrix-0.20.2-06677905efd8dea3cc2180d233c55f709d85b070d9a6c7d431d9ffdf8b4cb553:Internal.Element
    

    If you want the exact line numbers of where functions are called (rather than their definition site) there are some further options. The simplest is to enable -fprof-auto-calls on your package (cabal sadly does not know about auto-calls, so you can't use that as profiling-detail level). This yields the following output:

    $ cabal run --enable-profiling --ghc-options="-fprof-auto-calls" -v0
    hmatrix-backtrace: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
    
    nonconformable matrices in liftMatrix2Auto: (0x4), (4x1)
    
    Cost-centre stack backtrace:
      Main.CAF (<entire-module>)
      Main.main (app/Main.hs:(7,8)-(10,17))
      Main.main (app/Main.hs:9:3-120)
      Main.main (app/Main.hs:9:3-120)
      Main.main (app/Main.hs:9:13-119)
      GHC.Internal.Err.error (libraries/ghc-internal/src/GHC/Internal/Err.hs:36:1-5)
      GHC.Internal.Exception.errorCallWithCallStackException (libraries/ghc-internal/src/GHC/Internal/Exception.hs:199:1-31)
      GHC.Internal.Stack.withFrozenCallStack (libraries/ghc-internal/src/GHC/Internal/Stack.hs:101:1-19)
      GHC.Internal.Exception.Backtrace.collectBacktraces (libraries/ghc-internal/src/GHC/Internal/Exception/Backtrace.hs:136:1-17)
      GHC.Internal.Exception.Backtrace.collectBacktraces1 (<no location info>)
      GHC.Internal.Exception.Backtrace.$wcollectBacktraces (<no location info>)
    HasCallStack backtrace:
      error, called at src/Internal/Element.hs:488:19 in hmatrix-0.20.2-f3d3a8739e608ed9c5ba25610f4dae57ab72d24b511e878387c40807cb85e3db:Internal.Element
    

    This does not show liftMatrix2Auto, but it does show where it is called as Main.main (app/Main.hs:9:13-119). (Why the GHC developers chose to show this as Main.main is a mystery to me too.)