在使用gprolog时,我经常遇到没有任何行号或上下文的异常,如下所示:
uncaught exception: error(instantiation_error,(is)/2)
我知道我可以做一个trace,但是用trace调试它会花很长时间,因为我需要在到达错误发生的地方之前执行很多事情。你知道如何跟踪这个堆栈吗?或者动态的trace/notrace?编辑:或者只是自动打印整个trace输出。
trace
notrace
w41d8nur1#
@gusbro的答案(s(X))向您展示了如何使用GNU的调试器来解决这个问题。但是,如果您无法承受所有打印操作,或者它太慢,您可以考虑使用Scryer中的library(debug)“调试器”。我个人不使用Prolog系统提供的调试器,原因很简单,他们中的大多数打印得太多,本身经常有bug,并且有自己特定的不断变化的约定,我负担不起学习的费用。
s(X)
library(debug)
:- 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, *). *(_).
要使用它,只需在特定目标前面添加$-、$或@。$-表示:仅表示通过此目标的例外情况$还显示调用和退出@确保至少有一个答案,如果没有,则报告该答案并抛出异常。谨慎使用上述注解!*删除目标。这是为了在纯单调程序中泛化执行程序修改/program-slicing的程序。在意外失败的情况下需要此功能。有关如何使用它的示例,请参见以下解答/调试会话1、2、3、4、5、6、7、一个八个一个x、一个九个一个x、一个十个一个x、一个十一个一个x、一个十二个一个x、一个十三个一个x。_/*term*/用匿名变量替换术语。这比*本身更能推广程序。示例会话:第一个14英尺1x、第一个15英尺1x、第一个16英尺1x、第一个17英尺1x、第一个18英尺1x、第一个19英尺1x、第一个20英尺1x、第一个21英尺1x、第一个22英尺1x、第一个23英尺1x。通过这种方式,您可以显著减少所观看的信息。在其他支持meta_predicate指令的系统中,如SICStus、雅普和SWI,在前面添加以下指令:
$-
$
@
*
_/*term*/
meta_predicate
:- meta_predicate(( $-(0), $(0), @(0) )).
epfja78i2#
您只能对例外端口执行trace/0和leash/1操作,例如:
trace/0
leash/1
?- trace. ?- leash([exception]).
然后你运行你的程序,它会在屏幕上打印一个跟踪,但只有当异常发生时才会停止。在那里你可以通过按字母g看到 “堆栈跟踪”(祖先)。
g
2条答案
按热度按时间w41d8nur1#
@gusbro的答案(
s(X)
)向您展示了如何使用GNU的调试器来解决这个问题。但是,如果您无法承受所有打印操作,或者它太慢,您可以考虑使用Scryer中的library(debug)
“调试器”。我个人不使用Prolog系统提供的调试器,原因很简单,他们中的大多数打印得太多,本身经常有bug,并且有自己特定的不断变化的约定,我负担不起学习的费用。
要使用它,只需在特定目标前面添加
$-
、$
或@
。$-
表示:仅表示通过此目标的例外情况$
还显示调用和退出@
确保至少有一个答案,如果没有,则报告该答案并抛出异常。谨慎使用上述注解!
*
删除目标。这是为了在纯单调程序中泛化执行程序修改/program-slicing的程序。在意外失败的情况下需要此功能。有关如何使用它的示例,请参见以下解答/调试会话1、2、3、4、5、6、7、一个八个一个x、一个九个一个x、一个十个一个x、一个十一个一个x、一个十二个一个x、一个十三个一个x。_/*term*/
用匿名变量替换术语。这比*
本身更能推广程序。示例会话:第一个14英尺1x、第一个15英尺1x、第一个16英尺1x、第一个17英尺1x、第一个18英尺1x、第一个19英尺1x、第一个20英尺1x、第一个21英尺1x、第一个22英尺1x、第一个23英尺1x。通过这种方式,您可以显著减少所观看的信息。
在其他支持
meta_predicate
指令的系统中,如SICStus、雅普和SWI,在前面添加以下指令:epfja78i2#
您只能对例外端口执行
trace/0
和leash/1
操作,例如:然后你运行你的程序,它会在屏幕上打印一个跟踪,但只有当异常发生时才会停止。在那里你可以通过按字母
g
看到 “堆栈跟踪”(祖先)。