Как создать трассировку стека при делении на ноль с помощью ghc 7.10.3?
Если программа запускается и выдает сообщение "Разделить на ноль", каков наилучший способ определить, где в коде была сгенерирована эта ошибка?
1 ответ
GHC не поддерживает трассировки стека как таковые, потому что нет стека вызовов. Лучшее, что вы можете сделать, - это использовать механизм имитации трассировки стека в базовом модуле. GHC.Stack
,
Начиная с GHC 7.8 и, таким образом, доступно в 7.10.3, GHC.Stack
разоблачений
errorWithStackTrace :: String -> a
который действует как error
на обычных сборках, но использует аннотации SCC (например, из --fprof-auto
) построить приблизительную трассировку стека на профилированных сборках. Вам нужно будет перекомпилировать с включенным профилированием для поддержки этого. Если вы используете клику, вы можете запустить
cabal configure --enable-library-profiling --enable-executable-profiling
и восстановить.
Начиная с GHC 8.0, errorWithStackTrace
устарела, а поддержка генерации call-сайтов обеспечивается HasCallStack
техника.
Цитирую сейчас из GHC.Stack
документация,
Функция может запросить свой сайт вызова с
HasCallStack
ограничение. Например, мы можем определитьerrorWithCallStack :: HasCallStack => String -> a
как вариант
error
который получит свой call-сайт. Мы можем получить доступ к стеку вызовов внутриerrorWithCallStack
сcallStack
,errorWithCallStack :: HasCallStack => String -> a errorWithCallStack msg = error (msg ++ "n" ++ prettyCallStack callStack)
Таким образом, если мы называем
errorWithCallStack
мы получим отформатированный стек вызовов вместе с нашим сообщением об ошибке.>>> errorWithCallStack "die" *** Exception: die CallStack (from HasCallStack): errorWithCallStack, called at <interactive>:2:1 in interactive:Ghci1
(Я догадываюсь msg ++ "\n"
имелось в виду, но "n"
это то, что написано.)
Хотя вы можете получить очень ограниченную поддержку трассировки стека с GHC 7.8 и выше, я бы порекомендовал обновить GHC 8, если это возможно, для значительно лучшей поддержки. В любом случае, это не будет тем, к чему вы привыкли на других языках, но это лучше, чем ничего.