使用 gprolog 时,我经常会遇到没有任何行号或类似上下文的异常:
uncaught exception: error(instantiation_error,(is)/2)
没有任何背景。我知道我可以做trace
但是用trace
调试它需要很长时间,因为我需要在到达发生错误的地方之前执行很多事情。
有关如何进行此堆栈跟踪的任何想法?或动态trace
/ notrace
?
编辑:或者只是自动打印整个trace
输出。
答案 0 :(得分:9)
@ 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,
8
通过这种方式,您可以显着减少您所观看的信息。
在支持meta_predicate
指令(如SICStus,YAP和SWI)的其他系统中,请在前面添加以下指令:
:- meta_predicate(( $-(0), $(0), @(0) )).
答案 1 :(得分:8)
您可以trace/0
和leash/1
仅例外端口,例如:
?- trace.
?- leash([exception]).
然后运行程序,它将在屏幕上打印一条跟踪,但只有在发生异常时才会停止。在那里,你可以按字母g
看到“堆栈跟踪”(祖先)。