Как я могу получить позицию, в которой была вызвана ошибка?
Я ищу что-то, чтобы заменить loch (и его препроцессор), поскольку он не компилируется с помощью ghc 7.
В частности, если вызывается error
, то я хотел бы выяснить, насколько это возможно, где он был вызван (номер строки и трассировка стека были бы хороши).
Ответы
Ответ 1
Вы можете использовать опцию -xc
RTS, как описано на этой странице; вам нужно скомпилировать свою программу с помощью профилирования, а результат довольно уродлив, но он работает.
Это должно сделать это:
$ ghc --make -prof -auto-all myprog.hs
$ ./myprog +RTS -xc
Технически это дает только стек МВЗ, а не истинную трассировку стека. Улучшенная поддержка трассировки стека входит в GHC 7.4.
Ответ 2
Если это предназначено для использования в коде, над которым вы работаете, и вы можете терпеть использование Template Haskell, placeholders
пакет - это симпатичный и простой способ сделайте что-нибудь подобное. Это не поможет вам найти расположение фактических выражений error
, хотя и использует только собственные error
-подобные функции.
Ответ 3
Это довольно тривиально, чтобы построить его с помощью GHC-7. Это просто изменение Control.Exception
, которое появилось в 6.12, простое исправление - изменить тип Exception
на SomeException
в Debug.Trace.Location
, строка 70 и добавить подпись типа выражения в строке 144. Ограничить зависимость base
до >= 4.2 && < 4.6
в файле .cabal(bump the version), и вам хорошо идти.
Ответ 4
Быстрое n-грязное обходное решение - это функция assert
из Control.Exception. Однако, это немного clunkier чем error
.
Предупреждение.. Все утверждения будут игнорироваться при компиляции с оптимизацией (ghc -O1
, -O2
и т.д.).
Пример:
import Control.Exception
main = do
print (42 + (assert True 17)) -- adds 42 and 17
print (42 + (assert False 21)) -- crashes
Вывод:
59
test.hs: /tmp/test.hs:5:18-23: Assertion failed
Обратите внимание на номер строки "5" на выходе.
Вы можете использовать trace
из Debug.Trace, чтобы добавить сообщение об ошибке:
print (42 + (trace "omg error" $ assert False 21))