9

在使用gprolog 时,我经常遇到没有任何类型的行号或上下文的异常,例如:

uncaught exception: error(instantiation_error,(is)/2)

没有任何上下文。我知道我可以做,trace但是调试它需要很长时间,trace因为在到达错误发生的地方之前我需要执行很多事情。

关于如何拥有这个堆栈跟踪的任何想法?还是动态trace/ notrace

编辑:或者只是自动打印整个trace输出。

4

2 回答 2

12

@gusbro 的回答 ( s(X)) 向您展示了如何使用 GNU 的调试器解决这个问题。但是,如果您无法看到所有的打印正在进行,或者打印速度太慢,您可以考虑library(debug)在 Scryer 中提供以下“调试器”。

我个人不使用 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, *).
*(_).

要使用它,只需在特定目标前添加$-$或。@

$-表示:仅表示通过此目标的异常

$另外显示呼叫和退出

@确保至少有一个答案,如果没有,则报告并抛出异常。

谨慎使用上述注释!

*删除目标。这是为了概括在纯单调程序中进行程序修改/如果发生意外故障,您需要这个。有关如何使用它的示例,请参阅以下答案/调试会话 12345678910

_/*term*/用匿名变量替换术语。这比*单独更广泛地概括了一个程序。示例会话: 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10

通过这种方式,您可以显着减少您观看的信息。

meta_predicate在支持SICStus、YAP 和 SWI等指令的其他系统中,在前面添加以下指令:

:- meta_predicate(( $-(0), $(0), @(0) )).
于 2015-06-11T21:18:09.850 回答
9

您可以trace/0并且leash/1只有例外端口,例如:

?- trace.
?- leash([exception]).

然后你运行你的程序,它会在屏幕上打印一个跟踪,但只有在发生异常时才会停止。在那里,您可以通过按 letter来查看“堆栈跟踪”g (祖先) 。

于 2015-06-11T19:54:10.570 回答