У меня есть некоторый код синтаксического анализа с использованием Megaparsec, который я написал для тестирования простого свойства (оно генерирует случайное дерево выражений, красиво печатает его, а затем проверяет, что результат анализируется обратно в исходное дерево).
К сожалению, кажется, что есть ошибка, и если я запускаю тесты без каких-либо ограничений, я вижу, как процесс GHC выделяет все больше и больше памяти, пока я либо не уничтожу его, либо убийца OOM не доберется туда первым.
Не проблема, подумала я ... но я не могу на всю жизнь понять, что вызывает расхождение. Само свойство выглядит так: (Я вырвал правильное тестирование и сжатый код, чтобы попытаться свести к минимуму код, который фактически выполняется)
prop_parse_expr :: Property
prop_parse_expr =
forAll arbitrary $
(\ pe ->
let str = prettyParExpr 0 pe in
counterexample ("Rendered to: " ++ show str) $
trace ("STARTING TEST: " ++ show str) $
case parse (expr <* eof) "" str of
Left _ -> trace "NOPE" $ False
Right _ -> trace "GOOD" $ True)
Если я скомпилирую с профилированием (используя stack test --profile
)Я могу запустить полученный бинарный файл с опциями RTS. Ага, подумал я и побежал с -xc
, думая, что получу полезную трассировку стека, когда отправлю SIGINT на застрявшую работу. Кажется нет. Запуск с
./long/path/to/foo-test -j1 --test-seed 1 +RTS -xc
Я вижу этот вывод:
STARTING TEST: "0"
GOOD
STARTING TEST: "(x [( !0 )]) "
STARTING TEST: "({ 2 {( !0 )}} ) "
STARTING TEST: "{ 2{ ( x[0? {( 0) ,( x ) } :((0 )? (x ):0) -: ( -(^( x )) ) ]), 0**( x )} } "
STARTING TEST: "| (0? (x[({ 1{ (0)? x : ( 0 ) }} ) ]) :(~&( 0) ?( x):( (x ) ^( x ) )))"
STARTING TEST: "(0 )"
STARTING TEST: "0"
^C*** Exception (reporting due to +RTS -xc): (THUNK_STATIC), stack trace:
Test.Framework.Improving.runImprovingIO,
called from Test.Framework.Providers.QuickCheck2.runProperty,
called from Test.Framework.Providers.QuickCheck2.runTest,
called from Test.Framework.Runners.Core.runSimpleTest,
called from Test.Framework.Runners.Core.runTestTree.go,
called from Test.Framework.Runners.Core.runTestTree,
called from Test.Framework.Runners.Core.runTests',
called from Test.Framework.Runners.Core.runTests,
called from Test.Framework.Runners.Console.defaultMainWithOpts,
called from Test.Framework.Runners.Console.defaultMainWithArgs,
called from Test.Framework.Runners.Console.defaultMain,
called from Main.main
<snip: 2 more identical backtraces>
*** Exception (reporting due to +RTS -xc): (THUNK_STATIC), stack trace:
Test.Framework.Runners.Console.Utilities.hideCursorDuring,
called from Test.Framework.Runners.Console.Run.showRunTestsTop,
called from Test.Framework.Improving.runImprovingIO,
called from Test.Framework.Providers.QuickCheck2.runProperty,
called from Test.Framework.Providers.QuickCheck2.runTest,
called from Test.Framework.Runners.Core.runSimpleTest,
called from Test.Framework.Runners.Core.runTestTree.go,
called from Test.Framework.Runners.Core.runTestTree,
called from Test.Framework.Runners.Core.runTests',
called from Test.Framework.Runners.Core.runTests,
called from Test.Framework.Runners.Console.defaultMainWithOpts,
called from Test.Framework.Runners.Console.defaultMainWithArgs,
called from Test.Framework.Runners.Console.defaultMain,
called from Main.main
Может кто-нибудь сказать мне:
Почему я вижу несколько STARTING TEST
строкбез GOOD
или NOPE
между ними, несмотря на -j1?
Как получить фактическую трассировку стека, которая показывает, где тест выделяет всю свою память?
Спасибо за любые идеи!