gprolog: получение трассировки стека после исключения
При использовании gprolog у меня часто бывают исключения без каких-либо номеров строк или контекста, подобных этому:
uncaught exception: error(instantiation_error,(is)/2)
Без какого-либо контекста. Я знаю, что могу сделать trace
но это займет очень много времени, чтобы отладить его с trace
так как мне нужно выполнить много вещей, прежде чем добраться до места, где произошла ошибка.
Любая идея о том, как получить эту трассировку стека? Или динамический trace
/ notrace
?
РЕДАКТИРОВАТЬ: Или просто автоматизировать печать всего trace
выход.
2 ответа
Ответ @gusbro (s(X)
) показывает, как вы решаете эту проблему с помощью отладчика GNU. Однако, если вы не можете позволить себе видеть всю печать, или она слишком медленная, вы можете рассмотреть следующий "отладчик".
Лично я не использую отладчики, предлагаемые системами Prolog, по той простой причине, что большинство из них печатают слишком много, часто сами глючат и имеют свои собственные постоянно меняющиеся соглашения, которые я не могу себе позволить изучать.
:- op(900, fx, [@,$,$-]).
$-(G_0) :-
catch(G_0, Ex, ( portray_clause(exception:Ex:G_0), throw(Ex) ) ).
$(G_0) :-
portray_clause(call:G_0),
$-G_0,
portray_clause(exit:G_0).
@(G_0) :-
( $-G_0
*-> true
; portray_clause(badfail:G_0),
throw(goal_failed(G_0))
).
:- op(950, fy, *).
*(_).
Чтобы использовать это, просто добавьте $-
, $
, или же @
перед конкретной целью.
$-
означает: только исключения сигналов, проходящих через эту цель
$
дополнительно показать звонок и выход
@
гарантирует, что есть по крайней мере один ответ, и если нет, он сообщается и выдается исключение.
Используйте выше аннотации экономно!
*
удаляет цель. Это предназначено для обобщения программы, выполняющей модификацию / нарезку в чисто монотонной программе. Для примеров, как его использовать, смотрите следующие ответы / сеансы отладки 1, 2, 3, 4, 5, 6, 7, 8.
_/*term*/
заменяет термин на анонимную переменную. Это обобщает программу даже дальше, чем *
в одиночестве. Пример сеансов: 1, 2, 3, 4, 5, 6, 7.
Таким образом, вы можете значительно уменьшить информацию, которую вы смотрите.
В других системах поддержки meta_predicate
такие директивы, как SICStus, YAP и SWI, добавляют перед собой следующую директиву:
:- meta_predicate(( $-(0), $(0), @(0) )).
Ты можешь trace/0
а также leash/1
только порт исключения, например:
?- trace.
?- leash([exception]).
Затем вы запускаете свою программу, и она выводит на экран трассировку, но останавливается только при возникновении исключения. Там вы можете увидеть "след стека" (предки), нажав букву g
,