debugging gprolog:在异常后获取堆栈跟踪

vpfxa7rd  于 2023-02-13  发布在  其他
关注(0)|答案(2)|浏览(232)

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

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

我知道我可以做一个trace,但是用trace调试它会花很长时间,因为我需要在到达错误发生的地方之前执行很多事情。
你知道如何跟踪这个堆栈吗?或者动态的trace/notrace
编辑:或者只是自动打印整个trace输出。

w41d8nur

w41d8nur1#

@gusbro的答案(s(X))向您展示了如何使用GNU的调试器来解决这个问题。但是,如果您无法承受所有打印操作,或者它太慢,您可以考虑使用Scryer中的library(debug)“调试器”。
我个人不使用Prolog系统提供的调试器,原因很简单,他们中的大多数打印得太多,本身经常有bug,并且有自己特定的不断变化的约定,我负担不起学习的费用。

:- 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的程序。在意外失败的情况下需要此功能。有关如何使用它的示例,请参见以下解答/调试会话1234567、一个八个一个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,在前面添加以下指令:

:- meta_predicate(( $-(0), $(0), @(0) )).
epfja78i

epfja78i2#

您只能对例外端口执行trace/0leash/1操作,例如:

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

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

相关问题