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,

Другие вопросы по тегам